MDEV-506 Cassandra dynamic columns access
This commit is contained in:
parent
7327cd9717
commit
245298f25d
@ -39,6 +39,12 @@
|
|||||||
*/
|
*/
|
||||||
#define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL
|
#define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL
|
||||||
|
|
||||||
|
/*
|
||||||
|
Limits of implementation
|
||||||
|
*/
|
||||||
|
#define MAX_NAME_LENGTH 255
|
||||||
|
#define MAX_TOTAL_NAME_LENGTH 65535
|
||||||
|
|
||||||
/* NO and OK is the same used just to show semantics */
|
/* NO and OK is the same used just to show semantics */
|
||||||
#define ER_DYNCOL_NO ER_DYNCOL_OK
|
#define ER_DYNCOL_NO ER_DYNCOL_OK
|
||||||
|
|
||||||
@ -50,7 +56,8 @@ enum enum_dyncol_func_result
|
|||||||
ER_DYNCOL_LIMIT= -2, /* Some limit reached */
|
ER_DYNCOL_LIMIT= -2, /* Some limit reached */
|
||||||
ER_DYNCOL_RESOURCE= -3, /* Out of resourses */
|
ER_DYNCOL_RESOURCE= -3, /* Out of resourses */
|
||||||
ER_DYNCOL_DATA= -4, /* Incorrect input data */
|
ER_DYNCOL_DATA= -4, /* Incorrect input data */
|
||||||
ER_DYNCOL_UNKNOWN_CHARSET= -5 /* Unknown character set */
|
ER_DYNCOL_UNKNOWN_CHARSET= -5, /* Unknown character set */
|
||||||
|
ER_DYNCOL_TRUNCATED= 2 /* OK, but data was truncated */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DYNAMIC_STRING DYNAMIC_COLUMN;
|
typedef DYNAMIC_STRING DYNAMIC_COLUMN;
|
||||||
@ -81,6 +88,7 @@ struct st_dynamic_column_value
|
|||||||
struct {
|
struct {
|
||||||
LEX_STRING value;
|
LEX_STRING value;
|
||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset;
|
||||||
|
my_bool nonfreeable;
|
||||||
} string;
|
} string;
|
||||||
struct {
|
struct {
|
||||||
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
|
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
|
||||||
@ -108,6 +116,13 @@ dynamic_column_create_many_fmt(DYNAMIC_COLUMN *str,
|
|||||||
uchar *column_keys,
|
uchar *column_keys,
|
||||||
DYNAMIC_COLUMN_VALUE *values,
|
DYNAMIC_COLUMN_VALUE *values,
|
||||||
my_bool names);
|
my_bool names);
|
||||||
|
enum enum_dyncol_func_result
|
||||||
|
dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str,
|
||||||
|
uint column_count,
|
||||||
|
void *column_keys,
|
||||||
|
DYNAMIC_COLUMN_VALUE *values,
|
||||||
|
my_bool new_str,
|
||||||
|
my_bool string_keys);
|
||||||
|
|
||||||
enum enum_dyncol_func_result
|
enum enum_dyncol_func_result
|
||||||
dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr,
|
dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr,
|
||||||
@ -163,6 +178,21 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json);
|
|||||||
#define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A)))
|
#define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A)))
|
||||||
#define dynamic_column_column_free(V) dynstr_free(V)
|
#define dynamic_column_column_free(V) dynstr_free(V)
|
||||||
|
|
||||||
|
/* conversion of values to 3 base types */
|
||||||
|
enum enum_dyncol_func_result
|
||||||
|
dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
|
||||||
|
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...
|
Internal functions, don't use if you don't know what you are doing...
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
@ -365,8 +365,9 @@ CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA
|
|||||||
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4';
|
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4';
|
||||||
select * from t2;
|
select * from t2;
|
||||||
rowkey datecol
|
rowkey datecol
|
||||||
1 1346189025000
|
1 1346192625000
|
||||||
10 1346189026000
|
10 1346192626000
|
||||||
|
delete from t2;
|
||||||
drop table t2;
|
drop table t2;
|
||||||
#
|
#
|
||||||
# Check whether changing parameters with ALTER TABLE works.
|
# Check whether changing parameters with ALTER TABLE works.
|
||||||
@ -407,3 +408,141 @@ new-rowkey12 data1-value3 454
|
|||||||
rowkey11 updated-1 34543
|
rowkey11 updated-1 34543
|
||||||
delete from t1;
|
delete from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# Dynamic columns support
|
||||||
|
#
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
|
||||||
|
drop table t2;
|
||||||
|
#error: dynamic column is not a blob
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36) DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
|
||||||
|
ERROR 42000: Incorrect column specifier for column 'uuidcol'
|
||||||
|
#error: double dynamic column
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1, textcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
|
||||||
|
ERROR 42000: Incorrect column specifier for column 'textcol'
|
||||||
|
#
|
||||||
|
# Dynamic column read
|
||||||
|
#
|
||||||
|
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,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a');
|
||||||
|
drop table t2;
|
||||||
|
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
|
||||||
|
2 `uuidcol` 9b5658dc-f32f-11e1-94cd-f46d046e9f0a
|
||||||
|
drop table t2;
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA
|
||||||
|
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;
|
||||||
|
# bigint
|
||||||
|
CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'a', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'a', 2543));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"a":254324},{"dyn1":"1"},{"dyn2":"two"}]
|
||||||
|
2 [{"a":2543},{"dyn1":"1"},{"dyn2":"two"}]
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
# int
|
||||||
|
CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'intcol', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'intcol', 2543));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"dyn1":"1"},{"dyn2":"two"},{"intcol":254324}]
|
||||||
|
2 [{"dyn1":"1"},{"dyn2":"two"},{"intcol":2543}]
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
# timestamp
|
||||||
|
CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'datecol', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'datecol', 2543));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"dyn1":"1"},{"dyn2":"two"},{"datecol":254324}]
|
||||||
|
2 [{"dyn1":"1"},{"dyn2":"two"},{"datecol":2543}]
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
# boolean
|
||||||
|
CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 0));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":1}]
|
||||||
|
2 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":0}]
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":1}]
|
||||||
|
2 [{"dyn1":"1"},{"dyn2":"two"},{"boolcol":0}]
|
||||||
|
update t1 set dyn=column_add(dyn, "dyn2", null, "dyn3", "3");
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":1}]
|
||||||
|
2 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":0}]
|
||||||
|
update t1 set dyn=column_add(dyn, "dyn1", null) where rowkey= 1;
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"dyn3":"3"},{"boolcol":1}]
|
||||||
|
2 [{"dyn1":"1"},{"dyn3":"3"},{"boolcol":0}]
|
||||||
|
update t1 set dyn=column_add(dyn, "dyn3", null, "a", "ddd");
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"a":"ddd"},{"boolcol":1}]
|
||||||
|
2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0}]
|
||||||
|
update t1 set dyn=column_add(dyn, "12345678901234", "ddd");
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"a":"ddd"},{"boolcol":1},{"12345678901234":"ddd"}]
|
||||||
|
2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0},{"12345678901234":"ddd"}]
|
||||||
|
update t1 set dyn=column_add(dyn, "12345678901234", null);
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"a":"ddd"},{"boolcol":1}]
|
||||||
|
2 [{"a":"ddd"},{"dyn1":"1"},{"boolcol":0}]
|
||||||
|
update t1 set dyn=column_add(dyn, 'boolcol', null) where rowkey= 2;
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"a":"ddd"},{"boolcol":1}]
|
||||||
|
2 [{"a":"ddd"},{"dyn1":"1"}]
|
||||||
|
update t1 set rowkey= 3, dyn=column_add(dyn, "dyn1", null, 'boolcol', 0) where rowkey= 2;
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
rowkey column_json(dyn)
|
||||||
|
1 [{"a":"ddd"},{"boolcol":1}]
|
||||||
|
3 [{"a":"ddd"},{"boolcol":0}]
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd1';
|
||||||
|
select * from t1;
|
||||||
|
ERROR HY000: Internal error: 'Unable to convert value for field `dyn` from Cassandra's data format. Name length exceed limit of 255: 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_ver'
|
||||||
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes)
|
||||||
|
ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2';
|
||||||
|
DELETE FROM t1;
|
||||||
|
insert into t1 values (1, column_create("dyn", 1));
|
||||||
|
select rowkey, column_list(dyn) from t1;
|
||||||
|
rowkey column_list(dyn)
|
||||||
|
1 `dyn`
|
||||||
|
delete from t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes)
|
||||||
|
ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2';
|
||||||
|
insert into t1 values (1,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a');
|
||||||
|
ERROR HY000: Encountered illegal format of dynamic column string
|
||||||
|
delete from t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -89,6 +89,24 @@ The following options may be given as the first argument:
|
|||||||
--bulk-insert-buffer-size=#
|
--bulk-insert-buffer-size=#
|
||||||
Size of tree cache used in bulk insert optimisation. Note
|
Size of tree cache used in bulk insert optimisation. Note
|
||||||
that this is a limit per thread!
|
that this is a limit per thread!
|
||||||
|
--cassandra[=name] Enable or disable CASSANDRA plugin. Possible values are
|
||||||
|
ON, OFF, FORCE (don't start if the plugin fails to load).
|
||||||
|
--cassandra-default-thrift-host=name
|
||||||
|
Default host for Cassandra thrift connections
|
||||||
|
--cassandra-failure-retries=#
|
||||||
|
Number of times to retry Cassandra calls that failed due
|
||||||
|
to timeouts or network communication problems. The
|
||||||
|
default, 0, means not to retry.
|
||||||
|
--cassandra-insert-batch-size=#
|
||||||
|
Number of rows in an INSERT batch
|
||||||
|
--cassandra-multiget-batch-size=#
|
||||||
|
Number of rows in a multiget(MRR) batch
|
||||||
|
--cassandra-read-consistency=name
|
||||||
|
Cassandra consistency level to use for read operations
|
||||||
|
--cassandra-rnd-batch-size=#
|
||||||
|
Number of rows in an rnd_read (full scan) batch
|
||||||
|
--cassandra-write-consistency=name
|
||||||
|
Cassandra consistency level to use for write operations
|
||||||
--character-set-client-handshake
|
--character-set-client-handshake
|
||||||
Don't ignore client side character set value sent during
|
Don't ignore client side character set value sent during
|
||||||
handshake.
|
handshake.
|
||||||
@ -863,6 +881,14 @@ binlog-optimize-thread-scheduling TRUE
|
|||||||
binlog-row-event-max-size 1024
|
binlog-row-event-max-size 1024
|
||||||
binlog-stmt-cache-size 32768
|
binlog-stmt-cache-size 32768
|
||||||
bulk-insert-buffer-size 8388608
|
bulk-insert-buffer-size 8388608
|
||||||
|
cassandra ON
|
||||||
|
cassandra-default-thrift-host (No default value)
|
||||||
|
cassandra-failure-retries 0
|
||||||
|
cassandra-insert-batch-size 100
|
||||||
|
cassandra-multiget-batch-size 100
|
||||||
|
cassandra-read-consistency ONE
|
||||||
|
cassandra-rnd-batch-size 10000
|
||||||
|
cassandra-write-consistency ONE
|
||||||
character-set-client-handshake TRUE
|
character-set-client-handshake TRUE
|
||||||
character-set-filesystem binary
|
character-set-filesystem binary
|
||||||
character-set-server latin1
|
character-set-server latin1
|
||||||
|
@ -94,6 +94,18 @@ CREATE COLUMN FAMILY cf10
|
|||||||
WITH comparator = UTF8Type
|
WITH comparator = UTF8Type
|
||||||
AND key_validation_class=UTF8Type
|
AND key_validation_class=UTF8Type
|
||||||
AND default_validation_class = UTF8Type;
|
AND default_validation_class = UTF8Type;
|
||||||
|
|
||||||
|
CREATE COLUMN FAMILY cfd1
|
||||||
|
WITH comparator = UTF8Type
|
||||||
|
AND key_validation_class=UTF8Type
|
||||||
|
AND default_validation_class = UTF8Type;
|
||||||
|
SET cfd1['1']['very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_name']='1';
|
||||||
|
|
||||||
|
CREATE COLUMN FAMILY cfd2
|
||||||
|
WITH comparator = UTF8Type
|
||||||
|
AND key_validation_class=Int32Type
|
||||||
|
AND default_validation_class = UTF8Type;
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
--error 0,1,2
|
--error 0,1,2
|
||||||
@ -463,7 +475,7 @@ drop table t2;
|
|||||||
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, datecol bigint) ENGINE=CASSANDRA
|
||||||
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4';
|
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4';
|
||||||
select * from t2;
|
select * from t2;
|
||||||
|
delete from t2;
|
||||||
drop table t2;
|
drop table t2;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
@ -511,6 +523,118 @@ select * from t1;
|
|||||||
delete from t1;
|
delete from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Dynamic columns support
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
--echo #error: dynamic column is not a blob
|
||||||
|
--error ER_WRONG_FIELD_SPEC
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36) DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
|
||||||
|
|
||||||
|
--echo #error: double dynamic column
|
||||||
|
--error ER_WRONG_FIELD_SPEC
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol blob DYNAMIC_COLUMN_STORAGE=1, textcol blob DYNAMIC_COLUMN_STORAGE=1) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Dynamic column read
|
||||||
|
--echo #
|
||||||
|
#prepare data
|
||||||
|
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,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a');
|
||||||
|
drop table t2;
|
||||||
|
|
||||||
|
#test dynamic column read
|
||||||
|
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;
|
||||||
|
|
||||||
|
#cleanup data
|
||||||
|
CREATE TABLE t2 (rowkey bigint PRIMARY KEY, uuidcol char(36)) ENGINE=CASSANDRA
|
||||||
|
thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf5';
|
||||||
|
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;
|
||||||
|
--echo # bigint
|
||||||
|
CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf2';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'a', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'a', 2543));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
--echo # int
|
||||||
|
CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf3';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'intcol', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'intcol', 2543));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
--echo # timestamp
|
||||||
|
CREATE TABLE t1 (rowkey bigint PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf4';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'datecol', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'datecol', 2543));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
--echo # boolean
|
||||||
|
CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cf7';
|
||||||
|
insert into t1 values (1, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 254324));
|
||||||
|
insert into t1 values (2, column_create("dyn1", 1, "dyn2", "two", 'boolcol', 0));
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
update t1 set dyn=column_add(dyn, "dyn2", null, "dyn3", "3");
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
update t1 set dyn=column_add(dyn, "dyn1", null) where rowkey= 1;
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
update t1 set dyn=column_add(dyn, "dyn3", null, "a", "ddd");
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
update t1 set dyn=column_add(dyn, "12345678901234", "ddd");
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
update t1 set dyn=column_add(dyn, "12345678901234", null);
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
update t1 set dyn=column_add(dyn, 'boolcol', null) where rowkey= 2;
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
update t1 set rowkey= 3, dyn=column_add(dyn, "dyn1", null, 'boolcol', 0) where rowkey= 2;
|
||||||
|
select rowkey, column_json(dyn) from t1;
|
||||||
|
delete from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (rowkey varchar(10) PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes) ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd1';
|
||||||
|
--error ER_INTERNAL_ERROR
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
# MDEV-560
|
||||||
|
CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes)
|
||||||
|
ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2';
|
||||||
|
DELETE FROM t1;
|
||||||
|
insert into t1 values (1, column_create("dyn", 1));
|
||||||
|
select rowkey, column_list(dyn) from t1;
|
||||||
|
# Cleanup
|
||||||
|
delete from t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
# MDEV-561 (incorrect format data to dynamic column)
|
||||||
|
CREATE TABLE t1 (rowkey int PRIMARY KEY, dyn blob DYNAMIC_COLUMN_STORAGE=yes)
|
||||||
|
ENGINE=CASSANDRA thrift_host='localhost' keyspace='mariadbtest2' column_family = 'cfd2';
|
||||||
|
--error ER_DYN_COL_WRONG_FORMAT
|
||||||
|
insert into t1 values (1,'9b5658dc-f32f-11e1-94cd-f46d046e9f0a');
|
||||||
|
delete from t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
## Cassandra cleanup
|
## Cassandra cleanup
|
||||||
############################################################################
|
############################################################################
|
||||||
|
@ -68,6 +68,8 @@ uint32 copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
|
|||||||
|
|
||||||
#define MAX_OFFSET_LENGTH 5
|
#define MAX_OFFSET_LENGTH 5
|
||||||
|
|
||||||
|
#define DYNCOL_NUM_CHAR 6
|
||||||
|
|
||||||
my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str)
|
my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str)
|
||||||
{
|
{
|
||||||
if (str->length < 1)
|
if (str->length < 1)
|
||||||
@ -211,7 +213,7 @@ static my_bool check_limit_num(const void *val)
|
|||||||
|
|
||||||
static my_bool check_limit_str(const void *val)
|
static my_bool check_limit_str(const void *val)
|
||||||
{
|
{
|
||||||
return (*((LEX_STRING **)val))->length > 255;
|
return (*((LEX_STRING **)val))->length > MAX_NAME_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -288,7 +290,7 @@ my_bool put_header_entry_str(DYN_HEADER *hdr,
|
|||||||
size_t offset)
|
size_t offset)
|
||||||
{
|
{
|
||||||
LEX_STRING *column_name= (LEX_STRING *)column_key;
|
LEX_STRING *column_name= (LEX_STRING *)column_key;
|
||||||
DBUG_ASSERT(column_name->length <= 255);
|
DBUG_ASSERT(column_name->length <= MAX_NAME_LENGTH);
|
||||||
hdr->entry[0]= column_name->length;
|
hdr->entry[0]= column_name->length;
|
||||||
DBUG_ASSERT(hdr->name - hdr->nmpool < (long) 0x10000L);
|
DBUG_ASSERT(hdr->name - hdr->nmpool < (long) 0x10000L);
|
||||||
int2store(hdr->entry + 1, hdr->name - hdr->nmpool);
|
int2store(hdr->entry + 1, hdr->name - hdr->nmpool);
|
||||||
@ -1381,6 +1383,9 @@ dynamic_new_column_store(DYNAMIC_COLUMN *str,
|
|||||||
DYNCOL_SYZERESERVE))
|
DYNCOL_SYZERESERVE))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
if (!column_count)
|
||||||
|
return ER_DYNCOL_OK;
|
||||||
|
|
||||||
bzero(str->str, fmt->fixed_hdr);
|
bzero(str->str, fmt->fixed_hdr);
|
||||||
str->length= fmt->fixed_hdr;
|
str->length= fmt->fixed_hdr;
|
||||||
|
|
||||||
@ -1501,7 +1506,7 @@ calc_var_sizes(DYN_HEADER *hdr,
|
|||||||
@return ER_DYNCOL_* return code
|
@return ER_DYNCOL_* return code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static enum enum_dyncol_func_result
|
enum enum_dyncol_func_result
|
||||||
dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str,
|
dynamic_column_create_many_internal_fmt(DYNAMIC_COLUMN *str,
|
||||||
uint column_count,
|
uint column_count,
|
||||||
void *column_keys,
|
void *column_keys,
|
||||||
@ -1761,7 +1766,7 @@ static my_bool
|
|||||||
find_column(DYN_HEADER *hdr, uint numkey, LEX_STRING *strkey)
|
find_column(DYN_HEADER *hdr, uint numkey, LEX_STRING *strkey)
|
||||||
{
|
{
|
||||||
LEX_STRING nmkey;
|
LEX_STRING nmkey;
|
||||||
char nmkeybuff[6]; /* to fit max 2 bytes number */
|
char nmkeybuff[DYNCOL_NUM_CHAR]; /* to fit max 2 bytes number */
|
||||||
DBUG_ASSERT(hdr->header != NULL);
|
DBUG_ASSERT(hdr->header != NULL);
|
||||||
|
|
||||||
if (hdr->header + hdr->header_size > hdr->data_end)
|
if (hdr->header + hdr->header_size > hdr->data_end)
|
||||||
@ -2169,10 +2174,10 @@ dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr)
|
|||||||
if (header.format == DYNCOL_FMT_NUM)
|
if (header.format == DYNCOL_FMT_NUM)
|
||||||
{
|
{
|
||||||
uint nm= uint2korr(read);
|
uint nm= uint2korr(read);
|
||||||
tmp.str= my_malloc(6, MYF(0));
|
tmp.str= my_malloc(DYNCOL_NUM_CHAR, MYF(0));
|
||||||
if (!tmp.str)
|
if (!tmp.str)
|
||||||
return ER_DYNCOL_RESOURCE;
|
return ER_DYNCOL_RESOURCE;
|
||||||
tmp.length= snprintf(tmp.str, 6, "%u", nm);
|
tmp.length= snprintf(tmp.str, DYNCOL_NUM_CHAR, "%u", nm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2208,7 +2213,7 @@ find_place(DYN_HEADER *hdr, void *key, my_bool string_keys)
|
|||||||
uint mid, start, end, val;
|
uint mid, start, end, val;
|
||||||
int flag;
|
int flag;
|
||||||
LEX_STRING str;
|
LEX_STRING str;
|
||||||
char buff[6];
|
char buff[DYNCOL_NUM_CHAR];
|
||||||
my_bool need_conversion= ((string_keys ? DYNCOL_FMT_STR : DYNCOL_FMT_NUM) !=
|
my_bool need_conversion= ((string_keys ? DYNCOL_FMT_STR : DYNCOL_FMT_NUM) !=
|
||||||
hdr->format);
|
hdr->format);
|
||||||
LINT_INIT(flag); /* 100 % safe */
|
LINT_INIT(flag); /* 100 % safe */
|
||||||
@ -2425,7 +2430,7 @@ dynamic_column_update_copy(DYNAMIC_COLUMN *str, PLAN *plan,
|
|||||||
size_t offs;
|
size_t offs;
|
||||||
uint nm;
|
uint nm;
|
||||||
DYNAMIC_COLUMN_TYPE tp;
|
DYNAMIC_COLUMN_TYPE tp;
|
||||||
char buff[6];
|
char buff[DYNCOL_NUM_CHAR];
|
||||||
|
|
||||||
if (hdr->format == DYNCOL_FMT_NUM)
|
if (hdr->format == DYNCOL_FMT_NUM)
|
||||||
{
|
{
|
||||||
@ -3438,7 +3443,7 @@ end:
|
|||||||
|
|
||||||
enum enum_dyncol_func_result
|
enum enum_dyncol_func_result
|
||||||
dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
|
dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
|
||||||
my_bool quote)
|
CHARSET_INFO *cs, my_bool quote)
|
||||||
{
|
{
|
||||||
char buff[40];
|
char buff[40];
|
||||||
int len;
|
int len;
|
||||||
@ -3468,24 +3473,22 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
|
|||||||
char *alloc= NULL;
|
char *alloc= NULL;
|
||||||
char *from= val->x.string.value.str;
|
char *from= val->x.string.value.str;
|
||||||
uint bufflen;
|
uint bufflen;
|
||||||
my_bool conv= !my_charset_same(val->x.string.charset,
|
my_bool conv= !my_charset_same(val->x.string.charset, cs);
|
||||||
&my_charset_utf8_general_ci);
|
|
||||||
my_bool rc;
|
my_bool rc;
|
||||||
len= val->x.string.value.length;
|
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))
|
if (dynstr_realloc(str, bufflen))
|
||||||
return ER_DYNCOL_RESOURCE;
|
return ER_DYNCOL_RESOURCE;
|
||||||
|
|
||||||
// guaranty UTF-8 string for value
|
// guaranty UTF-8 string for value
|
||||||
if (!my_charset_same(val->x.string.charset,
|
if (!my_charset_same(val->x.string.charset, cs))
|
||||||
&my_charset_utf8_general_ci))
|
|
||||||
{
|
{
|
||||||
uint dummy_errors;
|
uint dummy_errors;
|
||||||
if (!quote)
|
if (!quote)
|
||||||
{
|
{
|
||||||
/* convert to the destination */
|
/* convert to the destination */
|
||||||
str->length+= copy_and_convert_extended(str->str, bufflen,
|
str->length+= copy_and_convert_extended(str->str, bufflen,
|
||||||
&my_charset_utf8_general_ci,
|
cs,
|
||||||
from, len,
|
from, len,
|
||||||
val->x.string.charset,
|
val->x.string.charset,
|
||||||
&dummy_errors);
|
&dummy_errors);
|
||||||
@ -3494,8 +3497,7 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
|
|||||||
if ((alloc= (char *)my_malloc(bufflen, MYF(0))))
|
if ((alloc= (char *)my_malloc(bufflen, MYF(0))))
|
||||||
{
|
{
|
||||||
len=
|
len=
|
||||||
copy_and_convert_extended(alloc, bufflen,
|
copy_and_convert_extended(alloc, bufflen, cs,
|
||||||
&my_charset_utf8_general_ci,
|
|
||||||
from, len, val->x.string.charset,
|
from, len, val->x.string.charset,
|
||||||
&dummy_errors);
|
&dummy_errors);
|
||||||
from= alloc;
|
from= alloc;
|
||||||
@ -3543,6 +3545,155 @@ dynamic_column_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
|
|||||||
return(ER_DYNCOL_OK);
|
return(ER_DYNCOL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum enum_dyncol_func_result
|
||||||
|
dynamic_column_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val)
|
||||||
|
{
|
||||||
|
enum enum_dyncol_func_result rc= ER_DYNCOL_OK;
|
||||||
|
*ll= 0;
|
||||||
|
switch (val->type) {
|
||||||
|
case DYN_COL_INT:
|
||||||
|
*ll= val->x.long_value;
|
||||||
|
break;
|
||||||
|
case DYN_COL_UINT:
|
||||||
|
*ll= (longlong)val->x.ulong_value;
|
||||||
|
if (val->x.ulong_value > ULONGLONG_MAX)
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
case DYN_COL_DOUBLE:
|
||||||
|
*ll= (longlong)val->x.double_value;
|
||||||
|
if (((double) *ll) != val->x.double_value)
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
case DYN_COL_STRING:
|
||||||
|
{
|
||||||
|
longlong i= 0, sign= 1;
|
||||||
|
char *src= val->x.string.value.str;
|
||||||
|
uint len= val->x.string.value.length;
|
||||||
|
|
||||||
|
while (len && my_isspace(&my_charset_latin1, *src)) src++,len--;
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
if (*src == '-')
|
||||||
|
{
|
||||||
|
sign= -1;
|
||||||
|
src++;
|
||||||
|
} else if (*src == '-')
|
||||||
|
src++;
|
||||||
|
while(len && my_isdigit(&my_charset_latin1, *src))
|
||||||
|
{
|
||||||
|
i= i * 10 + (*src - '0');
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
if (len)
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
*ll= i * sign;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DYN_COL_DECIMAL:
|
||||||
|
if (decimal2longlong(&val->x.decimal.value, ll) != E_DEC_OK)
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
case DYN_COL_DATETIME:
|
||||||
|
*ll= (val->x.time_value.year * 10000000000L +
|
||||||
|
val->x.time_value.month * 100000000L +
|
||||||
|
val->x.time_value.day * 1000000 +
|
||||||
|
val->x.time_value.hour * 10000 +
|
||||||
|
val->x.time_value.minute * 100 +
|
||||||
|
val->x.time_value.second) *
|
||||||
|
(val->x.time_value.neg ? -1 : 1);
|
||||||
|
break;
|
||||||
|
case DYN_COL_DATE:
|
||||||
|
*ll= (val->x.time_value.year * 10000 +
|
||||||
|
val->x.time_value.month * 100 +
|
||||||
|
val->x.time_value.day) *
|
||||||
|
(val->x.time_value.neg ? -1 : 1);
|
||||||
|
break;
|
||||||
|
case DYN_COL_TIME:
|
||||||
|
*ll= (val->x.time_value.hour * 10000 +
|
||||||
|
val->x.time_value.minute * 100 +
|
||||||
|
val->x.time_value.second) *
|
||||||
|
(val->x.time_value.neg ? -1 : 1);
|
||||||
|
break;
|
||||||
|
case DYN_COL_NULL:
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return(ER_DYNCOL_FORMAT);
|
||||||
|
}
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum enum_dyncol_func_result
|
||||||
|
dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val)
|
||||||
|
{
|
||||||
|
enum enum_dyncol_func_result rc= ER_DYNCOL_OK;
|
||||||
|
*dbl= 0;
|
||||||
|
switch (val->type) {
|
||||||
|
case DYN_COL_INT:
|
||||||
|
*dbl= (double)val->x.long_value;
|
||||||
|
if (((longlong) *dbl) != val->x.long_value)
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
case DYN_COL_UINT:
|
||||||
|
*dbl= (double)val->x.ulong_value;
|
||||||
|
if (((ulonglong) *dbl) != val->x.ulong_value)
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
case DYN_COL_DOUBLE:
|
||||||
|
*dbl= val->x.double_value;
|
||||||
|
break;
|
||||||
|
case DYN_COL_STRING:
|
||||||
|
{
|
||||||
|
char *str, *end;
|
||||||
|
if ((str= malloc(val->x.string.value.length + 1)))
|
||||||
|
return ER_DYNCOL_RESOURCE;
|
||||||
|
memcpy(str, val->x.string.value.str, val->x.string.value.length);
|
||||||
|
str[val->x.string.value.length]= '\0';
|
||||||
|
*dbl= strtod(str, &end);
|
||||||
|
if (*end != '\0')
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
}
|
||||||
|
case DYN_COL_DECIMAL:
|
||||||
|
if (decimal2double(&val->x.decimal.value, dbl) != E_DEC_OK)
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
case DYN_COL_DATETIME:
|
||||||
|
*dbl= (double)(val->x.time_value.year * 10000000000L +
|
||||||
|
val->x.time_value.month * 100000000L +
|
||||||
|
val->x.time_value.day * 1000000 +
|
||||||
|
val->x.time_value.hour * 10000 +
|
||||||
|
val->x.time_value.minute * 100 +
|
||||||
|
val->x.time_value.second) *
|
||||||
|
(val->x.time_value.neg ? -1 : 1);
|
||||||
|
break;
|
||||||
|
case DYN_COL_DATE:
|
||||||
|
*dbl= (double)(val->x.time_value.year * 10000 +
|
||||||
|
val->x.time_value.month * 100 +
|
||||||
|
val->x.time_value.day) *
|
||||||
|
(val->x.time_value.neg ? -1 : 1);
|
||||||
|
break;
|
||||||
|
case DYN_COL_TIME:
|
||||||
|
*dbl= (double)(val->x.time_value.hour * 10000 +
|
||||||
|
val->x.time_value.minute * 100 +
|
||||||
|
val->x.time_value.second) *
|
||||||
|
(val->x.time_value.neg ? -1 : 1);
|
||||||
|
break;
|
||||||
|
case DYN_COL_NULL:
|
||||||
|
rc= ER_DYNCOL_TRUNCATED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return(ER_DYNCOL_FORMAT);
|
||||||
|
}
|
||||||
|
return(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convert to JSON
|
Convert to JSON
|
||||||
|
|
||||||
@ -3602,10 +3753,11 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json)
|
|||||||
if (header.format == DYNCOL_FMT_NUM)
|
if (header.format == DYNCOL_FMT_NUM)
|
||||||
{
|
{
|
||||||
uint nm= uint2korr(header.entry);
|
uint nm= uint2korr(header.entry);
|
||||||
if (dynstr_realloc(json, 6 + 3))
|
if (dynstr_realloc(json, DYNCOL_NUM_CHAR + 3))
|
||||||
goto err;
|
goto err;
|
||||||
json->str[json->length++]= '"';
|
json->str[json->length++]= '"';
|
||||||
json->length+= (snprintf(json->str + json->length, 6, "%u", nm));
|
json->length+= (snprintf(json->str + json->length,
|
||||||
|
DYNCOL_NUM_CHAR, "%u", nm));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3619,7 +3771,8 @@ dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json)
|
|||||||
}
|
}
|
||||||
json->str[json->length++]= '"';
|
json->str[json->length++]= '"';
|
||||||
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))
|
dynstr_append_mem(json, "}", 1))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -3631,3 +3784,99 @@ err:
|
|||||||
json->length= 0;
|
json->length= 0;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert to DYNAMIC_COLUMN_VALUE values and names (LEX_STING) dynamic array
|
||||||
|
|
||||||
|
@param str The packed string
|
||||||
|
@param names Where to put names
|
||||||
|
@param vals Where to put values
|
||||||
|
@param free_names pointer to free names buffer if there is it.
|
||||||
|
|
||||||
|
@return ER_DYNCOL_* return code
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum enum_dyncol_func_result
|
||||||
|
dynamic_column_vals(DYNAMIC_COLUMN *str,
|
||||||
|
DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals,
|
||||||
|
char **free_names)
|
||||||
|
{
|
||||||
|
DYN_HEADER header;
|
||||||
|
char *nm;
|
||||||
|
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)
|
||||||
|
return ER_DYNCOL_OK; /* no columns */
|
||||||
|
|
||||||
|
if ((rc= init_read_hdr(&header, str)) < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (header.entry_size * header.column_count + FIXED_HEADER_SIZE >
|
||||||
|
str->length)
|
||||||
|
return ER_DYNCOL_FORMAT;
|
||||||
|
|
||||||
|
if (init_dynamic_array(names, sizeof(LEX_STRING),
|
||||||
|
header.column_count, 0) ||
|
||||||
|
init_dynamic_array(vals, sizeof(DYNAMIC_COLUMN_VALUE),
|
||||||
|
header.column_count, 0) ||
|
||||||
|
(header.format == DYNCOL_FMT_NUM &&
|
||||||
|
!(*free_names= (char *)malloc(DYNCOL_NUM_CHAR * header.column_count))))
|
||||||
|
{
|
||||||
|
rc= ER_DYNCOL_RESOURCE;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
nm= *free_names;
|
||||||
|
|
||||||
|
for (i= 0, header.entry= header.header;
|
||||||
|
i < header.column_count;
|
||||||
|
i++, header.entry+= header.entry_size)
|
||||||
|
{
|
||||||
|
DYNAMIC_COLUMN_VALUE val;
|
||||||
|
LEX_STRING name;
|
||||||
|
header.length=
|
||||||
|
hdr_interval_length(&header, header.entry + header.entry_size);
|
||||||
|
header.data= header.dtpool + header.offset;
|
||||||
|
/*
|
||||||
|
Check that the found data is withing the ranges. This can happen if
|
||||||
|
we get data with wrong offsets.
|
||||||
|
*/
|
||||||
|
if (header.length == DYNCOL_OFFSET_ERROR ||
|
||||||
|
header.length > INT_MAX || header.offset > header.data_size)
|
||||||
|
{
|
||||||
|
rc= ER_DYNCOL_FORMAT;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if ((rc= dynamic_column_get_value(&header, &val)) < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (header.format == DYNCOL_FMT_NUM)
|
||||||
|
{
|
||||||
|
uint num= uint2korr(header.entry);
|
||||||
|
name.str= nm;
|
||||||
|
name.length= snprintf(nm, DYNCOL_NUM_CHAR, "%u", num);
|
||||||
|
nm+= name.length + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name.length= header.entry[0];
|
||||||
|
name.str= (char *)header.nmpool + uint2korr(header.entry + 1);
|
||||||
|
}
|
||||||
|
/* following is preallocated and so do not fail */
|
||||||
|
(void) insert_dynamic(names, (uchar *)&name);
|
||||||
|
(void) insert_dynamic(vals, (uchar *)&val);
|
||||||
|
}
|
||||||
|
return ER_DYNCOL_OK;
|
||||||
|
|
||||||
|
err:
|
||||||
|
delete_dynamic(names);
|
||||||
|
delete_dynamic(vals);
|
||||||
|
if (*free_names)
|
||||||
|
my_free(*free_names);
|
||||||
|
*free_names= 0;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@ -9773,6 +9773,7 @@ int dynamic_column_error_message(enum_dyncol_func_result rc)
|
|||||||
switch (rc) {
|
switch (rc) {
|
||||||
case ER_DYNCOL_YES:
|
case ER_DYNCOL_YES:
|
||||||
case ER_DYNCOL_OK:
|
case ER_DYNCOL_OK:
|
||||||
|
case ER_DYNCOL_TRUNCATED:
|
||||||
break; // it is not an error
|
break; // it is not an error
|
||||||
case ER_DYNCOL_FORMAT:
|
case ER_DYNCOL_FORMAT:
|
||||||
my_error(ER_DYN_COL_WRONG_FORMAT, MYF(0));
|
my_error(ER_DYN_COL_WRONG_FORMAT, MYF(0));
|
||||||
|
@ -272,6 +272,7 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
|
|||||||
const char *table_name);
|
const char *table_name);
|
||||||
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
|
bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
|
||||||
|
|
||||||
|
class Open_tables_backup;
|
||||||
/* Functions to work with system tables. */
|
/* Functions to work with system tables. */
|
||||||
bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
|
bool open_system_tables_for_read(THD *thd, TABLE_LIST *table_list,
|
||||||
Open_tables_backup *backup);
|
Open_tables_backup *backup);
|
||||||
|
@ -12,7 +12,7 @@ SET(cassandra_sources
|
|||||||
gen-cpp/Cassandra.h)
|
gen-cpp/Cassandra.h)
|
||||||
|
|
||||||
#INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS})
|
#INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS})
|
||||||
INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/)
|
INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift)
|
||||||
#
|
#
|
||||||
STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||||
STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||||
|
@ -17,6 +17,12 @@
|
|||||||
|
|
||||||
#include "cassandra_se.h"
|
#include "cassandra_se.h"
|
||||||
|
|
||||||
|
struct st_mysql_lex_string
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace apache::thrift;
|
using namespace apache::thrift;
|
||||||
using namespace apache::thrift::transport;
|
using namespace apache::thrift::transport;
|
||||||
@ -74,6 +80,7 @@ class Cassandra_se_impl: public Cassandra_se_interface
|
|||||||
std::string rowkey; /* key of the record we're returning now */
|
std::string rowkey; /* key of the record we're returning now */
|
||||||
|
|
||||||
SlicePredicate slice_pred;
|
SlicePredicate slice_pred;
|
||||||
|
SliceRange slice_pred_sr;
|
||||||
bool get_slices_returned_less;
|
bool get_slices_returned_less;
|
||||||
bool get_slice_found_rows;
|
bool get_slice_found_rows;
|
||||||
public:
|
public:
|
||||||
@ -91,6 +98,8 @@ public:
|
|||||||
void first_ddl_column();
|
void first_ddl_column();
|
||||||
bool next_ddl_column(char **name, int *name_len, char **value, int *value_len);
|
bool next_ddl_column(char **name, int *name_len, char **value, int *value_len);
|
||||||
void get_rowkey_type(char **name, char **type);
|
void get_rowkey_type(char **name, char **type);
|
||||||
|
size_t get_ddl_size();
|
||||||
|
const char* get_default_validator();
|
||||||
|
|
||||||
/* Settings */
|
/* Settings */
|
||||||
void set_consistency_levels(ulong read_cons_level, ulong write_cons_level);
|
void set_consistency_levels(ulong read_cons_level, ulong write_cons_level);
|
||||||
@ -98,15 +107,19 @@ public:
|
|||||||
/* Writes */
|
/* Writes */
|
||||||
void clear_insert_buffer();
|
void clear_insert_buffer();
|
||||||
void start_row_insert(const char *key, int key_len);
|
void start_row_insert(const char *key, int key_len);
|
||||||
void add_insert_column(const char *name, const char *value, int value_len);
|
void add_insert_column(const char *name, int name_len,
|
||||||
|
const char *value, int value_len);
|
||||||
|
void add_insert_delete_column(const char *name, int name_len);
|
||||||
void add_row_deletion(const char *key, int key_len,
|
void add_row_deletion(const char *key, int key_len,
|
||||||
Column_name_enumerator *col_names);
|
Column_name_enumerator *col_names,
|
||||||
|
LEX_STRING *names, uint nnames);
|
||||||
|
|
||||||
bool do_insert();
|
bool do_insert();
|
||||||
|
|
||||||
/* Reads, point lookups */
|
/* Reads, point lookups */
|
||||||
bool get_slice(char *key, size_t key_len, bool *found);
|
bool get_slice(char *key, size_t key_len, bool *found);
|
||||||
bool get_next_read_column(char **name, char **value, int *value_len);
|
bool get_next_read_column(char **name, int *name_len,
|
||||||
|
char **value, int *value_len );
|
||||||
void get_read_rowkey(char **value, int *value_len);
|
void get_read_rowkey(char **value, int *value_len);
|
||||||
|
|
||||||
/* Reads, multi-row scans */
|
/* Reads, multi-row scans */
|
||||||
@ -122,6 +135,7 @@ public:
|
|||||||
|
|
||||||
/* Setup that's necessary before a multi-row read. (todo: use it before point lookups, too) */
|
/* Setup that's necessary before a multi-row read. (todo: use it before point lookups, too) */
|
||||||
void clear_read_columns();
|
void clear_read_columns();
|
||||||
|
void clear_read_all_columns();
|
||||||
void add_read_column(const char *name);
|
void add_read_column(const char *name);
|
||||||
|
|
||||||
/* Reads, MRR scans */
|
/* Reads, MRR scans */
|
||||||
@ -277,6 +291,16 @@ void Cassandra_se_impl::get_rowkey_type(char **name, char **type)
|
|||||||
*name= NULL;
|
*name= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Cassandra_se_impl::get_ddl_size()
|
||||||
|
{
|
||||||
|
return cf_def.column_metadata.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Cassandra_se_impl::get_default_validator()
|
||||||
|
{
|
||||||
|
return cf_def.default_validation_class.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Data writes
|
// Data writes
|
||||||
@ -315,8 +339,9 @@ void Cassandra_se_impl::start_row_insert(const char *key, int key_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cassandra_se_impl::add_row_deletion(const char *key, int key_len,
|
void Cassandra_se_impl::add_row_deletion(const char *key, int key_len,
|
||||||
Column_name_enumerator *col_names)
|
Column_name_enumerator *col_names,
|
||||||
|
LEX_STRING *names, uint nnames)
|
||||||
{
|
{
|
||||||
std::string key_to_delete;
|
std::string key_to_delete;
|
||||||
key_to_delete.assign(key, key_len);
|
key_to_delete.assign(key, key_len);
|
||||||
@ -344,6 +369,9 @@ void Cassandra_se_impl::add_row_deletion(const char *key, int key_len,
|
|||||||
const char *col_name;
|
const char *col_name;
|
||||||
while ((col_name= col_names->get_next_name()))
|
while ((col_name= col_names->get_next_name()))
|
||||||
slice_pred.column_names.push_back(std::string(col_name));
|
slice_pred.column_names.push_back(std::string(col_name));
|
||||||
|
for (uint i= 0; i < nnames; i++)
|
||||||
|
slice_pred.column_names.push_back(std::string(names[i].str,
|
||||||
|
names[i].length));
|
||||||
|
|
||||||
mut.deletion.predicate= slice_pred;
|
mut.deletion.predicate= slice_pred;
|
||||||
|
|
||||||
@ -351,7 +379,9 @@ void Cassandra_se_impl::add_row_deletion(const char *key, int key_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cassandra_se_impl::add_insert_column(const char *name, const char *value,
|
void Cassandra_se_impl::add_insert_column(const char *name,
|
||||||
|
int name_len,
|
||||||
|
const char *value,
|
||||||
int value_len)
|
int value_len)
|
||||||
{
|
{
|
||||||
Mutation mut;
|
Mutation mut;
|
||||||
@ -359,7 +389,10 @@ void Cassandra_se_impl::add_insert_column(const char *name, const char *value,
|
|||||||
mut.column_or_supercolumn.__isset.column= true;
|
mut.column_or_supercolumn.__isset.column= true;
|
||||||
|
|
||||||
Column& col=mut.column_or_supercolumn.column;
|
Column& col=mut.column_or_supercolumn.column;
|
||||||
col.name.assign(name);
|
if (name_len)
|
||||||
|
col.name.assign(name, name_len);
|
||||||
|
else
|
||||||
|
col.name.assign(name);
|
||||||
col.value.assign(value, value_len);
|
col.value.assign(value, value_len);
|
||||||
col.timestamp= insert_timestamp;
|
col.timestamp= insert_timestamp;
|
||||||
col.__isset.value= true;
|
col.__isset.value= true;
|
||||||
@ -367,6 +400,23 @@ void Cassandra_se_impl::add_insert_column(const char *name, const char *value,
|
|||||||
insert_list->push_back(mut);
|
insert_list->push_back(mut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cassandra_se_impl::add_insert_delete_column(const char *name,
|
||||||
|
int name_len)
|
||||||
|
{
|
||||||
|
Mutation mut;
|
||||||
|
mut.__isset.deletion= true;
|
||||||
|
mut.deletion.__isset.timestamp= true;
|
||||||
|
mut.deletion.timestamp= insert_timestamp;
|
||||||
|
mut.deletion.__isset.predicate= true;
|
||||||
|
|
||||||
|
SlicePredicate slice_pred;
|
||||||
|
slice_pred.__isset.column_names= true;
|
||||||
|
slice_pred.column_names.push_back(std::string(name, name_len));
|
||||||
|
mut.deletion.predicate= slice_pred;
|
||||||
|
|
||||||
|
insert_list->push_back(mut);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Cassandra_se_impl::retryable_do_insert()
|
bool Cassandra_se_impl::retryable_do_insert()
|
||||||
{
|
{
|
||||||
@ -444,8 +494,8 @@ bool Cassandra_se_impl::retryable_get_slice()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Cassandra_se_impl::get_next_read_column(char **name, char **value,
|
bool Cassandra_se_impl::get_next_read_column(char **name, int *name_len,
|
||||||
int *value_len)
|
char **value, int *value_len)
|
||||||
{
|
{
|
||||||
bool use_counter=false;
|
bool use_counter=false;
|
||||||
while (1)
|
while (1)
|
||||||
@ -468,12 +518,14 @@ bool Cassandra_se_impl::get_next_read_column(char **name, char **value,
|
|||||||
ColumnOrSuperColumn& cs= *column_data_it;
|
ColumnOrSuperColumn& cs= *column_data_it;
|
||||||
if (use_counter)
|
if (use_counter)
|
||||||
{
|
{
|
||||||
|
*name_len= cs.counter_column.name.size();
|
||||||
*name= (char*)cs.counter_column.name.c_str();
|
*name= (char*)cs.counter_column.name.c_str();
|
||||||
*value= (char*)&cs.counter_column.value;
|
*value= (char*)&cs.counter_column.value;
|
||||||
*value_len= sizeof(cs.counter_column.value);
|
*value_len= sizeof(cs.counter_column.value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
*name_len= cs.column.name.size();
|
||||||
*name= (char*)cs.column.name.c_str();
|
*name= (char*)cs.column.name.c_str();
|
||||||
*value= (char*)cs.column.value.c_str();
|
*value= (char*)cs.column.value.c_str();
|
||||||
*value_len= cs.column.value.length();
|
*value_len= cs.column.value.length();
|
||||||
@ -601,6 +653,13 @@ void Cassandra_se_impl::clear_read_columns()
|
|||||||
slice_pred.column_names.clear();
|
slice_pred.column_names.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cassandra_se_impl::clear_read_all_columns()
|
||||||
|
{
|
||||||
|
slice_pred_sr.start = "";
|
||||||
|
slice_pred_sr.finish = "";
|
||||||
|
slice_pred.__set_slice_range(slice_pred_sr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Cassandra_se_impl::add_read_column(const char *name_arg)
|
void Cassandra_se_impl::add_read_column(const char *name_arg)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
both together causes compile errors due to conflicts).
|
both together causes compile errors due to conflicts).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct st_mysql_lex_string;
|
||||||
|
typedef struct st_mysql_lex_string LEX_STRING;
|
||||||
|
|
||||||
/* We need to define this here so that ha_cassandra.cc also has access to it */
|
/* We need to define this here so that ha_cassandra.cc also has access to it */
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -50,19 +52,25 @@ public:
|
|||||||
virtual bool next_ddl_column(char **name, int *name_len, char **value,
|
virtual bool next_ddl_column(char **name, int *name_len, char **value,
|
||||||
int *value_len)=0;
|
int *value_len)=0;
|
||||||
virtual void get_rowkey_type(char **name, char **type)=0;
|
virtual void get_rowkey_type(char **name, char **type)=0;
|
||||||
|
virtual size_t get_ddl_size()=0;
|
||||||
|
virtual const char* get_default_validator()=0;
|
||||||
|
|
||||||
/* Writes */
|
/* Writes */
|
||||||
virtual void clear_insert_buffer()=0;
|
virtual void clear_insert_buffer()=0;
|
||||||
virtual void add_row_deletion(const char *key, int key_len,
|
virtual void add_row_deletion(const char *key, int key_len,
|
||||||
Column_name_enumerator *col_names)=0;
|
Column_name_enumerator *col_names,
|
||||||
|
LEX_STRING *names, uint nnames)=0;
|
||||||
virtual void start_row_insert(const char *key, int key_len)=0;
|
virtual void start_row_insert(const char *key, int key_len)=0;
|
||||||
virtual void add_insert_column(const char *name, const char *value,
|
virtual void add_insert_delete_column(const char *name, int name_len)= 0;
|
||||||
|
virtual void add_insert_column(const char *name, int name_len,
|
||||||
|
const char *value,
|
||||||
int value_len)=0;
|
int value_len)=0;
|
||||||
virtual bool do_insert()=0;
|
virtual bool do_insert()=0;
|
||||||
|
|
||||||
/* Reads */
|
/* Reads */
|
||||||
virtual bool get_slice(char *key, size_t key_len, bool *found)=0 ;
|
virtual bool get_slice(char *key, size_t key_len, bool *found)=0 ;
|
||||||
virtual bool get_next_read_column(char **name, char **value, int *value_len)=0;
|
virtual bool get_next_read_column(char **name, int *name_len,
|
||||||
|
char **value, int *value_len)=0;
|
||||||
virtual void get_read_rowkey(char **value, int *value_len)=0;
|
virtual void get_read_rowkey(char **value, int *value_len)=0;
|
||||||
|
|
||||||
/* Reads, multi-row scans */
|
/* Reads, multi-row scans */
|
||||||
@ -70,7 +78,7 @@ public:
|
|||||||
virtual bool get_range_slices(bool last_key_as_start_key)=0;
|
virtual bool get_range_slices(bool last_key_as_start_key)=0;
|
||||||
virtual void finish_reading_range_slices()=0;
|
virtual void finish_reading_range_slices()=0;
|
||||||
virtual bool get_next_range_slice_row(bool *eof)=0;
|
virtual bool get_next_range_slice_row(bool *eof)=0;
|
||||||
|
|
||||||
/* Reads, MRR scans */
|
/* Reads, MRR scans */
|
||||||
virtual void new_lookup_keys()=0;
|
virtual void new_lookup_keys()=0;
|
||||||
virtual int add_lookup_key(const char *key, size_t key_len)=0;
|
virtual int add_lookup_key(const char *key, size_t key_len)=0;
|
||||||
@ -79,8 +87,9 @@ public:
|
|||||||
|
|
||||||
/* read_set setup */
|
/* read_set setup */
|
||||||
virtual void clear_read_columns()=0;
|
virtual void clear_read_columns()=0;
|
||||||
|
virtual void clear_read_all_columns()=0;
|
||||||
virtual void add_read_column(const char *name)=0;
|
virtual void add_read_column(const char *name)=0;
|
||||||
|
|
||||||
virtual bool truncate()=0;
|
virtual bool truncate()=0;
|
||||||
virtual bool remove_row()=0;
|
virtual bool remove_row()=0;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ namespace org { namespace apache { namespace cassandra {
|
|||||||
const cassandraConstants g_cassandra_constants;
|
const cassandraConstants g_cassandra_constants;
|
||||||
|
|
||||||
cassandraConstants::cassandraConstants() {
|
cassandraConstants::cassandraConstants() {
|
||||||
cassandra_const_VERSION = "19.32.0";
|
cassandra_const_VERSION = (char *)"19.32.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
}}} // namespace
|
}}} // namespace
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -40,6 +40,33 @@ class ColumnDataConverter;
|
|||||||
|
|
||||||
struct ha_table_option_struct;
|
struct ha_table_option_struct;
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
enum cassandtra_type_enum {CT_BIGINT, CT_INT, CT_COUNTER, CT_FLOAT, CT_DOUBLE,
|
||||||
|
CT_BLOB, CT_ASCII, CT_TEXT, CT_TIMESTAMP, CT_UUID, CT_BOOLEAN, CT_VARINT,
|
||||||
|
CT_DECIMAL};
|
||||||
|
|
||||||
|
typedef enum cassandtra_type_enum CASSANDRA_TYPE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/** @brief
|
||||||
Class definition for the storage engine
|
Class definition for the storage engine
|
||||||
*/
|
*/
|
||||||
@ -48,23 +75,35 @@ class ha_cassandra: public handler
|
|||||||
friend class Column_name_enumerator_impl;
|
friend class Column_name_enumerator_impl;
|
||||||
THR_LOCK_DATA lock; ///< MySQL lock
|
THR_LOCK_DATA lock; ///< MySQL lock
|
||||||
CASSANDRA_SHARE *share; ///< Shared lock info
|
CASSANDRA_SHARE *share; ///< Shared lock info
|
||||||
|
|
||||||
Cassandra_se_interface *se;
|
Cassandra_se_interface *se;
|
||||||
|
|
||||||
|
/* description of static part of the table definition */
|
||||||
ColumnDataConverter **field_converters;
|
ColumnDataConverter **field_converters;
|
||||||
uint n_field_converters;
|
uint n_field_converters;
|
||||||
|
|
||||||
|
CASSANDRA_TYPE_DEF *default_type_def;
|
||||||
|
/* description of dynamic columns part */
|
||||||
|
CASSANDRA_TYPE_DEF *special_type_field_converters;
|
||||||
|
LEX_STRING *special_type_field_names;
|
||||||
|
uint n_special_type_fields;
|
||||||
|
DYNAMIC_ARRAY dynamic_values, dynamic_names;
|
||||||
|
DYNAMIC_STRING dynamic_rec;
|
||||||
|
|
||||||
ColumnDataConverter *rowkey_converter;
|
ColumnDataConverter *rowkey_converter;
|
||||||
|
|
||||||
bool setup_field_converters(Field **field, uint n_fields);
|
bool setup_field_converters(Field **field, uint n_fields);
|
||||||
void free_field_converters();
|
void free_field_converters();
|
||||||
|
|
||||||
int read_cassandra_columns(bool unpack_pk);
|
int read_cassandra_columns(bool unpack_pk);
|
||||||
int check_table_options(struct ha_table_option_struct* options);
|
int check_table_options(struct ha_table_option_struct* options);
|
||||||
|
|
||||||
bool doing_insert_batch;
|
bool doing_insert_batch;
|
||||||
ha_rows insert_rows_batched;
|
ha_rows insert_rows_batched;
|
||||||
|
|
||||||
|
uint dyncol_field;
|
||||||
|
bool dyncol_set;
|
||||||
|
|
||||||
/* Used to produce 'wrong column %s at row %lu' warnings */
|
/* Used to produce 'wrong column %s at row %lu' warnings */
|
||||||
ha_rows insert_lineno;
|
ha_rows insert_lineno;
|
||||||
void print_conversion_error(const char *field_name,
|
void print_conversion_error(const char *field_name,
|
||||||
@ -191,6 +230,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool source_exhausted;
|
bool source_exhausted;
|
||||||
bool mrr_start_read();
|
bool mrr_start_read();
|
||||||
|
int check_field_options(Field **fields);
|
||||||
|
int read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names,
|
||||||
|
String *valcol, char **freenames);
|
||||||
|
int write_dynamic_row(DYNAMIC_ARRAY *names, DYNAMIC_ARRAY *vals);
|
||||||
|
void static free_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names,
|
||||||
|
char *free_names);
|
||||||
|
CASSANDRA_TYPE_DEF * get_cassandra_field_def(char *cass_name,
|
||||||
|
int cass_name_length);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user