1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

backport to 5.5 dyncol changes and names support

This commit is contained in:
unknown
2012-12-23 20:57:54 +02:00
parent 28c9e1a550
commit 40ae63dd65
19 changed files with 1428 additions and 782 deletions

View File

@ -38,12 +38,13 @@
how the offset are stored.
*/
#define MAX_DYNAMIC_COLUMN_LENGTH 0X1FFFFFFFL
#define MAX_DYNAMIC_COLUMN_LENGTH_NM 0XFFFFFFFFFL
/*
Limits of implementation
*/
#define MAX_NAME_LENGTH 255
#define MAX_TOTAL_NAME_LENGTH 65535
#define MAX_NAME_LENGTH (MAX_TOTAL_NAME_LENGTH/4)
/* NO and OK is the same used just to show semantics */
#define ER_DYNCOL_NO ER_DYNCOL_OK
@ -72,7 +73,8 @@ enum enum_dynamic_column_type
DYN_COL_DECIMAL,
DYN_COL_DATETIME,
DYN_COL_DATE,
DYN_COL_TIME
DYN_COL_TIME,
DYN_COL_DYNCOL
};
typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE;
@ -88,7 +90,6 @@ struct st_dynamic_column_value
struct {
LEX_STRING value;
CHARSET_INFO *charset;
my_bool nonfreeable;
} string;
struct {
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
@ -100,6 +101,8 @@ struct st_dynamic_column_value
typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;
/* old functions (deprecated) */
#ifdef MADYNCOL_DEPRECATED
enum enum_dyncol_func_result
dynamic_column_create(DYNAMIC_COLUMN *str,
uint column_nr, DYNAMIC_COLUMN_VALUE *value);
@ -109,21 +112,6 @@ dynamic_column_create_many(DYNAMIC_COLUMN *str,
uint column_count,
uint *column_numbers,
DYNAMIC_COLUMN_VALUE *values);
enum enum_dyncol_func_result
dynamic_column_create_many_fmt(DYNAMIC_COLUMN *str,
uint column_count,
uchar *column_keys,
DYNAMIC_COLUMN_VALUE *values,
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
dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr,
DYNAMIC_COLUMN_VALUE *value);
@ -133,73 +121,105 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str,
uint *column_numbers,
DYNAMIC_COLUMN_VALUE *values);
enum enum_dyncol_func_result
dynamic_column_update_many_fmt(DYNAMIC_COLUMN *str,
uint add_column_count,
void *column_keys,
DYNAMIC_COLUMN_VALUE *values,
my_bool string_keys);
enum enum_dyncol_func_result
dynamic_column_delete(DYNAMIC_COLUMN *org, uint column_nr);
enum enum_dyncol_func_result
dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr);
enum enum_dyncol_func_result
dynamic_column_exists_str(DYNAMIC_COLUMN *str, LEX_STRING *name);
dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint);
enum enum_dyncol_func_result
dynamic_column_exists_fmt(DYNAMIC_COLUMN *str, void *key, my_bool string_keys);
dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr,
DYNAMIC_COLUMN_VALUE *store_it_here);
#endif
/* new functions */
enum enum_dyncol_func_result
mariadb_dyncol_create_many(DYNAMIC_COLUMN *str,
uint column_count,
uint *column_numbers,
DYNAMIC_COLUMN_VALUE *values,
my_bool new_string);
enum enum_dyncol_func_result
mariadb_dyncol_create_many_named(DYNAMIC_COLUMN *str,
uint column_count,
LEX_STRING *column_keys,
DYNAMIC_COLUMN_VALUE *values,
my_bool new_string);
enum enum_dyncol_func_result
mariadb_dyncol_update_many(DYNAMIC_COLUMN *str,
uint add_column_count,
uint *column_keys,
DYNAMIC_COLUMN_VALUE *values);
enum enum_dyncol_func_result
mariadb_dyncol_update_many_named(DYNAMIC_COLUMN *str,
uint add_column_count,
LEX_STRING *column_keys,
DYNAMIC_COLUMN_VALUE *values);
enum enum_dyncol_func_result
mariadb_dyncol_exists(DYNAMIC_COLUMN *org, uint column_nr);
enum enum_dyncol_func_result
mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, LEX_STRING *name);
/* List of not NULL columns */
enum enum_dyncol_func_result
dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint);
mariadb_dyncol_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint);
enum enum_dyncol_func_result
dynamic_column_list_str(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array_of_lexstr);
enum enum_dyncol_func_result
dynamic_column_list_fmt(DYNAMIC_COLUMN *str, DYNAMIC_ARRAY *array, my_bool string_keys);
mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *count, LEX_STRING **names);
/*
if the column do not exists it is NULL
*/
enum enum_dyncol_func_result
dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr,
mariadb_dyncol_get(DYNAMIC_COLUMN *org, uint column_nr,
DYNAMIC_COLUMN_VALUE *store_it_here);
enum enum_dyncol_func_result
dynamic_column_get_str(DYNAMIC_COLUMN *str, LEX_STRING *name,
mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, LEX_STRING *name,
DYNAMIC_COLUMN_VALUE *store_it_here);
my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str);
my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str);
enum enum_dyncol_func_result
dynamic_column_check(DYNAMIC_COLUMN *str);
mariadb_dyncol_check(DYNAMIC_COLUMN *str);
enum enum_dyncol_func_result
dynamic_column_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json);
mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json);
#define dynamic_column_initialize(A) memset((A), 0, sizeof(*(A)))
#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,
mariadb_dyncol_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);
mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val);
enum enum_dyncol_func_result
dynamic_column_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val);
mariadb_dyncol_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);
mariadb_dyncol_unpack(DYNAMIC_COLUMN *str,
uint *count,
LEX_STRING **names, DYNAMIC_COLUMN_VALUE **vals);
int mariadb_dyncol_column_cmp_named(const LEX_STRING *s1, const LEX_STRING *s2);
enum enum_dyncol_func_result
mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count);
/***************************************************************************
Internal functions, don't use if you don't know what you are doing...
***************************************************************************/
#define dynamic_column_reassociate(V,P,L, A) dynstr_reassociate((V),(P),(L),(A))
#define mariadb_dyncol_reassociate(V,P,L, A) dynstr_reassociate((V),(P),(L),(A))
#define dynamic_column_value_init(V) (V)->type= DYN_COL_NULL
#define dyncol_value_init(V) (V)->type= DYN_COL_NULL
/*
Prepare value for using as decimal

View File

@ -794,11 +794,16 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
extern my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append,
...);
extern my_bool dynstr_append_quoted(DYNAMIC_STRING *str,
const char *append, size_t len);
const char *append, size_t len,
char quote);
extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size);
extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n);
extern void dynstr_free(DYNAMIC_STRING *str);
extern uint32 copy_and_convert_extended(char *to, uint32 to_length,
CHARSET_INFO *to_cs,
const char *from, uint32 from_length,
CHARSET_INFO *from_cs, uint *errors);
extern void dynstr_reassociate(DYNAMIC_STRING *str, char **res, size_t *length,
size_t *alloc_length);
extern uint32 copy_and_convert_extended(char *to, uint32 to_length,

View File

@ -532,7 +532,7 @@ 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'
ERROR HY000: Internal error: 'Unable to convert value for field `dyn` from Cassandra's data format. Name length exceed limit of 16383: 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_v'
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';

View File

@ -1342,22 +1342,22 @@ hex(COLUMN_CREATE(0, 0.0 as decimal))
set names utf8;
select hex(column_create("адын", 1212));
hex(column_create("адын", 1212))
040100080008000000D0B0D0B4D18BD0BD7809
040100080000000000D0B0D0B4D18BD0BD7809
select hex(column_create("1212", 1212));
hex(column_create("1212", 1212))
040100040004000000313231327809
040100040000000000313231327809
select hex(column_create(1212, 2, "www", 3));
hex(column_create(1212, 2, "www", 3))
04020007000300000004030008777777313231320604
04020007000000000003001000777777313231320604
select hex(column_create("1212", 2, "www", 3));
hex(column_create("1212", 2, "www", 3))
04020007000300000004030008777777313231320604
04020007000000000003001000777777313231320604
select hex(column_create("1212", 2, 3, 3));
hex(column_create("1212", 2, 3, 3))
0402000500010000000401000833313231320604
0402000500000000000100100033313231320604
select hex(column_create("1212", 2, "адын", 1, 3, 3));
hex(column_create("1212", 2, "адын", 1, 3, 3))
0403000D000100000004010008080500103331323132D0B0D0B4D18BD0BD060402
0403000D000000000001001000050020003331323132D0B0D0B4D18BD0BD060402
set names default;
# fetching column test (names)
set names utf8;
@ -1413,10 +1413,10 @@ set names default;
# column changing test (names)
select hex(column_add(column_create(1, "AAA"), "b", "BBB"));
hex(column_add(column_create(1, "AAA"), "b", "BBB"))
0402000200010000030101002331620841414108424242
0402000200000003000100430031620841414108424242
select hex(column_add(column_create("1", "AAA"), "b", "BBB"));
hex(column_add(column_create("1", "AAA"), "b", "BBB"))
0402000200010000030101002331620841414108424242
0402000200000003000100430031620841414108424242
select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char);
column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char)
AAA
@ -1425,25 +1425,25 @@ column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char)
BBB
select hex(column_add(column_create("a", "AAA"), 1, "BBB"));
hex(column_add(column_create("a", "AAA"), 1, "BBB"))
0402000200010000030101002331610842424208414141
0402000200000003000100430031610842424208414141
select hex(column_add(column_create("a", "AAA"), "1", "BBB"));
hex(column_add(column_create("a", "AAA"), "1", "BBB"))
0402000200010000030101002331610842424208414141
0402000200000003000100430031610842424208414141
select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer));
hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer))
04020002000100000001010010616278097809
04020002000000000001002000616278097809
select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer));
hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer))
040100010001000000617809
040100010000000000617809
select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer));
hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer))
0400000000
select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer));
hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer))
040100010001000000617809
040100010000000000617809
select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer));
hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer))
040200020001000000010100086162167809
040200020000000000010010006162167809
select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer);
column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer)
11
@ -1452,13 +1452,13 @@ column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer,
1212
select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer));
hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer))
040200020001000000010100106162780916
040200020000000000010020006162780916
select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer));
hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer))
040200020001000000010100106162780916
040200020000000000010020006162780916
select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer));
hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer))
040200020001000000010100086162167809
040200020000000000010010006162167809
select hex(column_add(column_create("a", 1), "a", null));
hex(column_add(column_create("a", 1), "a", null))
0400000000
@ -1470,29 +1470,29 @@ column_list(column_add(column_create("a", 1), "a", ""))
`a`
select hex(column_add("", "a", 1));
hex(column_add("", "a", 1))
0401000100010000006102
0401000100000000006102
# column delete (names)
select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a"));
hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a"))
040100010001000000627809
040100010000000000627809
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b"));
hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b"))
0402000200010000000101000861630206
0402000200000000000100100061630206
select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer));
hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer))
0403000300010000000101000801020010616263020406
0403000300000000000100100002002000616263020406
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c"));
hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c"))
0402000200010000000101000861620204
0402000200000000000100100061620204
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d"));
hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d"))
0403000300010000000101000801020010616263020406
0403000300000000000100100002002000616263020406
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a"));
hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a"))
0401000100010000006306
0401000100000000006306
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c"));
hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c"))
0401000100010000006102
0401000100000000006102
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c"));
hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c"))
0400000000
@ -1517,11 +1517,21 @@ ERROR 42S22: Unknown column 'color' in 'field list'
#
CREATE TABLE t1 (f1 tinyblob);
INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30)));
select column_check(f1) from t1;
column_check(f1)
1
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' );
Warnings:
Warning 1265 Data truncated for column 'f1' at row 1
select column_check(f1) from t1;
column_check(f1)
0
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' );
ERROR HY000: Encountered illegal format of dynamic column string
Warnings:
Warning 1265 Data truncated for column 'f1' at row 1
select column_check(f1) from t1;
column_check(f1)
0
drop table t1;
#
# MDEV-490/MDEV-491 null as arguments
@ -1550,8 +1560,8 @@ NULL
#
SELECT hex(COLUMN_CREATE(REPEAT('a',255),1));
hex(COLUMN_CREATE(REPEAT('a',255),1))
040100FF00FF00000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616102
SELECT hex(COLUMN_CREATE(REPEAT('a',256),1));
040100FF000000000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616102
SELECT hex(COLUMN_CREATE(REPEAT('a',65536),1));
ERROR 22007: Illegal value used as argument of dynamic column function
#
# JSON conversion
@ -1577,3 +1587,53 @@ COLUMN_CHECK('')
SELECT COLUMN_CHECK(NULL);
COLUMN_CHECK(NULL)
NULL
#
# escaping check
#
select column_json(column_create("string", "'\"/\\`.,whatever")),hex(column_create("string", "'\"/\\`.,whatever"));
column_json(column_create("string", "'\"/\\`.,whatever")) hex(column_create("string", "'\"/\\`.,whatever"))
[{"string":"'\"/\\`.,whatever"}] 040100060000000300737472696E670827222F5C602E2C7768617465766572
#
# embedding test
#
select column_json(column_create("val", "val", "emb", column_create("val2", "val2")));
column_json(column_create("val", "val", "emb", column_create("val2", "val2")))
[{"emb":[{"val2":"val2"}],{"val":"val"}]
select column_json(column_create(1, "val", 2, column_create(3, "val2")));
column_json(column_create(1, "val", 2, column_create(3, "val2")))
[{"1":"val"},{"2":[{"3":"val2"}]]
#
# Time encoding
#
select hex(column_create("t", "800:46:06.23434" AS time)) as hex,
column_json(column_create("t", "800:46:06.23434" AS time)) as json;
hex json
04010001000000070074649363B82003 [{"t":"800:46:06.234340"}]
select hex(column_create(1, "800:46:06.23434" AS time)) as hex,
column_json(column_create(1, "800:46:06.23434" AS time)) as json;
hex json
000100010007649363B82003 [{"1":"800:46:06.234340"}]
select hex(column_create("t", "800:46:06" AS time)) as hex,
column_json(column_create("t", "800:46:06" AS time)) as json;
hex json
04010001000000070074860B32 [{"t":"800:46:06"}]
select hex(column_create(1, "800:46:06" AS time)) as hex,
column_json(column_create(1, "800:46:06" AS time)) as json;
hex json
000100010007000060B82003 [{"1":"800:46:06"}]
select hex(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as hex,
column_json(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as json;
hex json
0401000100000005007495B90F649363B80A00 [{"t":"2012-12-21 10:46:06.234340"}]
select hex(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as hex,
column_json(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as json;
hex json
00010001000595B90F649363B80A00 [{"1":"2012-12-21 10:46:06.234340"}]
select hex(column_create("t", "2012-12-21 10:46:06" AS datetime)) as hex,
column_json(column_create("t", "2012-12-21 10:46:06" AS datetime)) as json;
hex json
0401000100000005007495B90F86AB00 [{"t":"2012-12-21 10:46:06"}]
select hex(column_create(1, "2012-12-21 10:46:06" AS datetime)) as hex,
column_json(column_create(1, "2012-12-21 10:46:06" AS datetime)) as json;
hex json
00010001000595B90F000060B80A00 [{"1":"2012-12-21 10:46:06"}]

File diff suppressed because one or more lines are too long

View File

@ -636,9 +636,14 @@ select COLUMN_CREATE(color, "black");
CREATE TABLE t1 (f1 tinyblob);
INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30)));
select column_check(f1) from t1;
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' );
--error ER_DYN_COL_WRONG_FORMAT
# we can't detect last string cut with 100% probability,
# because we detect it by string end
select column_check(f1) from t1;
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' );
select column_check(f1) from t1;
drop table t1;
--echo #
@ -657,7 +662,7 @@ SELECT COLUMN_ADD( NULL, 'val', 'col');
--echo #
SELECT hex(COLUMN_CREATE(REPEAT('a',255),1));
--error ER_DYN_COL_DATA
SELECT hex(COLUMN_CREATE(REPEAT('a',256),1));
SELECT hex(COLUMN_CREATE(REPEAT('a',65536),1));
--echo #
--echo # JSON conversion
@ -672,3 +677,37 @@ SELECT COLUMN_CHECK(COLUMN_CREATE(1,'a'));
SELECT COLUMN_CHECK('abracadabra');
SELECT COLUMN_CHECK('');
SELECT COLUMN_CHECK(NULL);
--echo #
--echo # escaping check
--echo #
select column_json(column_create("string", "'\"/\\`.,whatever")),hex(column_create("string", "'\"/\\`.,whatever"));
--echo #
--echo # embedding test
--echo #
select column_json(column_create("val", "val", "emb", column_create("val2", "val2")));
select column_json(column_create(1, "val", 2, column_create(3, "val2")));
--echo #
--echo # Time encoding
--echo #
select hex(column_create("t", "800:46:06.23434" AS time)) as hex,
column_json(column_create("t", "800:46:06.23434" AS time)) as json;
select hex(column_create(1, "800:46:06.23434" AS time)) as hex,
column_json(column_create(1, "800:46:06.23434" AS time)) as json;
select hex(column_create("t", "800:46:06" AS time)) as hex,
column_json(column_create("t", "800:46:06" AS time)) as json;
select hex(column_create(1, "800:46:06" AS time)) as hex,
column_json(column_create(1, "800:46:06" AS time)) as json;
select hex(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as hex,
column_json(column_create("t", "2012-12-21 10:46:06.23434" AS datetime)) as json;
select hex(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as hex,
column_json(column_create(1, "2012-12-21 10:46:06.23434" AS datetime)) as json;
select hex(column_create("t", "2012-12-21 10:46:06" AS datetime)) as hex,
column_json(column_create("t", "2012-12-21 10:46:06" AS datetime)) as json;
select hex(column_create(1, "2012-12-21 10:46:06" AS datetime)) as hex,
column_json(column_create(1, "2012-12-21 10:46:06" AS datetime)) as json;

File diff suppressed because it is too large Load Diff

View File

@ -176,18 +176,19 @@ my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
}
my_bool dynstr_append_quoted(DYNAMIC_STRING *str,
const char *append, size_t len)
const char *append, size_t len,
char quote)
{
uint additional= (str->alloc_increment ? str->alloc_increment : 10);
uint lim= additional;
uint i;
if (dynstr_realloc(str, len + additional + 2))
return TRUE;
str->str[str->length++]= '"';
str->str[str->length++]= quote;
for (i= 0; i < len; i++)
{
register char c= append[i];
if (c == '"' || c == '\\')
if (c == quote || c == '\\')
{
if (!lim)
{
@ -200,10 +201,11 @@ my_bool dynstr_append_quoted(DYNAMIC_STRING *str,
}
str->str[str->length++]= c;
}
str->str[str->length++]= '"';
str->str[str->length++]= quote;
return FALSE;
}
void dynstr_free(DYNAMIC_STRING *str)
{
my_free(str->str);

View File

@ -6048,6 +6048,7 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item)
return NULL;
}
longlong Item_func_dyncol_check::val_int()
{
char buff[STRING_BUFFER_USUAL_SIZE];
@ -6062,7 +6063,7 @@ longlong Item_func_dyncol_check::val_int()
col.length= str->length();
/* We do not change the string, so could do this trick */
col.str= (char *)str->ptr();
rc= dynamic_column_check(&col);
rc= mariadb_dyncol_check(&col);
if (rc < 0 && rc != ER_DYNCOL_FORMAT)
{
dynamic_column_error_message(rc);
@ -6127,8 +6128,8 @@ longlong Item_func_dyncol_exists::val_int()
/* We do not change the string, so could do this trick */
col.str= (char *)str->ptr();
rc= ((name == NULL) ?
dynamic_column_exists(&col, (uint) num) :
dynamic_column_exists_str(&col, name));
mariadb_dyncol_exists(&col, (uint) num) :
mariadb_dyncol_exists_named(&col, name));
if (rc < 0)
{
dynamic_column_error_message(rc);

View File

@ -526,6 +526,54 @@ protected:
virtual ~Create_func_coercibility() {}
};
class Create_func_dyncol_check : public Create_func_arg1
{
public:
virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dyncol_check s_singleton;
protected:
Create_func_dyncol_check() {}
virtual ~Create_func_dyncol_check() {}
};
class Create_func_dyncol_exists : public Create_func_arg2
{
public:
virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_dyncol_exists s_singleton;
protected:
Create_func_dyncol_exists() {}
virtual ~Create_func_dyncol_exists() {}
};
class Create_func_dyncol_list : public Create_func_arg1
{
public:
virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dyncol_list s_singleton;
protected:
Create_func_dyncol_list() {}
virtual ~Create_func_dyncol_list() {}
};
class Create_func_dyncol_json : public Create_func_arg1
{
public:
virtual Item *create_1_arg(THD *thd, Item *arg1);
static Create_func_dyncol_json s_singleton;
protected:
Create_func_dyncol_json() {}
virtual ~Create_func_dyncol_json() {}
};
class Create_func_compress : public Create_func_arg1
{
@ -3108,6 +3156,38 @@ Create_func_coercibility::create_1_arg(THD *thd, Item *arg1)
}
Create_func_dyncol_check Create_func_dyncol_check::s_singleton;
Item*
Create_func_dyncol_check::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dyncol_check(arg1);
}
Create_func_dyncol_exists Create_func_dyncol_exists::s_singleton;
Item*
Create_func_dyncol_exists::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_dyncol_exists(arg1, arg2);
}
Create_func_dyncol_list Create_func_dyncol_list::s_singleton;
Item*
Create_func_dyncol_list::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dyncol_list(arg1);
}
Create_func_dyncol_json Create_func_dyncol_json::s_singleton;
Item*
Create_func_dyncol_json::create_1_arg(THD *thd, Item *arg1)
{
return new (thd->mem_root) Item_func_dyncol_json(arg1);
}
Create_func_concat Create_func_concat::s_singleton;
Item*
@ -5245,6 +5325,10 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)},
{ { C_STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)},
{ { C_STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)},
{ { C_STRING_WITH_LEN("COLUMN_CHECK") }, BUILDER(Create_func_dyncol_check)},
{ { C_STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)},
{ { C_STRING_WITH_LEN("COLUMN_LIST") }, BUILDER(Create_func_dyncol_list)},
{ { C_STRING_WITH_LEN("COLUMN_JSON") }, BUILDER(Create_func_dyncol_json)},
{ { C_STRING_WITH_LEN("COMPRESS") }, BUILDER(Create_func_compress)},
{ { C_STRING_WITH_LEN("CONCAT") }, BUILDER(Create_func_concat)},
{ { C_STRING_WITH_LEN("CONCAT_WS") }, BUILDER(Create_func_concat_ws)},
@ -5720,11 +5804,6 @@ Item *create_func_dyncol_create(THD *thd, List<DYNCALL_CREATE_DEF> &list)
return new (thd->mem_root) Item_func_dyncol_create(*args, dfs);
}
Item *create_func_dyncol_json(THD *thd, Item *str)
{
return new (thd->mem_root) Item_func_dyncol_json(str);
}
Item *create_func_dyncol_add(THD *thd, Item *str,
List<DYNCALL_CREATE_DEF> &list)
{

View File

@ -58,7 +58,7 @@ public:
NOW_FUNC, TRIG_COND_FUNC,
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC,
NEG_FUNC, GSYSVAR_FUNC };
NEG_FUNC, GSYSVAR_FUNC, DYNCOL };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }

View File

@ -3760,8 +3760,8 @@ String *Item_func_uuid::val_str(String *str)
Item_func_dyncol_create::Item_func_dyncol_create(List<Item> &args,
DYNCALL_CREATE_DEF *dfs)
: Item_str_func(args), defs(dfs), vals(0), keys(NULL), names(FALSE),
force_names(FALSE)
: Item_str_func(args), defs(dfs), vals(0), keys_num(NULL), keys_str(NULL),
names(FALSE), force_names(FALSE)
{
DBUG_ASSERT((args.elements & 0x1) == 0); // even number of arguments
}
@ -3782,13 +3782,15 @@ bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref)
names= TRUE;
}
keys= (uchar *) alloc_root(thd->mem_root,
keys_num= (uint *) alloc_root(thd->mem_root,
(sizeof(LEX_STRING) > sizeof(uint) ?
sizeof(LEX_STRING) :
sizeof(uint)) *
(arg_count / 2));
keys_str= (LEX_STRING *) keys_num;
//status_var_increment(thd->status_var.feature_dynamic_columns);
}
return res || vals == 0 || keys == 0;
return res || vals == 0 || keys_num == 0;
}
@ -3808,6 +3810,41 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
my_decimal dtmp, *dres;
force_names= force_names_arg;
if (!(names || force_names))
{
for (i= 0; i < column_count; i++)
{
uint valpos= i * 2 + 1;
DYNAMIC_COLUMN_TYPE type= defs[i].type;
if (type == DYN_COL_NULL)
switch (args[valpos]->field_type())
{
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_GEOMETRY:
type= DYN_COL_STRING;
break;
default:
break;
}
if (type == DYN_COL_STRING &&
args[valpos]->type() == Item::FUNC_ITEM &&
((Item_func *)args[valpos])->functype() == DYNCOL)
{
force_names= 1;
break;
}
}
}
/* get values */
for (i= 0; i < column_count; i++)
{
@ -3865,6 +3902,13 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
break;
}
}
if (type == DYN_COL_STRING &&
args[valpos]->type() == Item::FUNC_ITEM &&
((Item_func *)args[valpos])->functype() == DYNCOL)
{
DBUG_ASSERT(names || force_names);
type= DYN_COL_DYNCOL;
}
if (names || force_names)
{
res= args[i * 2]->val_str(&tmp);
@ -3873,10 +3917,8 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
// guaranty UTF-8 string for names
if (my_charset_same(res->charset(), &my_charset_utf8_general_ci))
{
((LEX_STRING *)keys)[i].length= res->length();
if (!(((LEX_STRING *)keys)[i].str=
(char *)sql_memdup(res->ptr(), res->length())))
((LEX_STRING *)keys)[i].length= 0;
keys_str[i].length= res->length();
keys_str[i].str= sql_strmake(res->ptr(), res->length());
}
else
{
@ -3887,25 +3929,25 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
my_charset_utf8_general_ci.mbmaxlen + 1));
if (str)
{
((LEX_STRING *)keys)[i].length=
keys_str[i].length=
copy_and_convert(str, strlen, &my_charset_utf8_general_ci,
res->ptr(), res->length(), res->charset(),
&dummy_errors);
((LEX_STRING *)keys)[i].str= str;
keys_str[i].str= str;
}
else
((LEX_STRING *)keys)[i].length= 0;
keys_str[i].length= 0;
}
}
else
{
((LEX_STRING *)keys)[i].length= 0;
((LEX_STRING *)keys)[i].str= NULL;
keys_str[i].length= 0;
keys_str[i].str= NULL;
}
}
else
((uint *)keys)[i]= (uint) args[i * 2]->val_int();
keys_num[i]= (uint) args[i * 2]->val_int();
if (args[i * 2]->null_value)
{
/* to make cleanup possible */
@ -3927,11 +3969,11 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
case DYN_COL_DOUBLE:
vals[i].x.double_value= args[valpos]->val_real();
break;
case DYN_COL_DYNCOL:
case DYN_COL_STRING:
res= args[valpos]->val_str(&tmp);
if (res &&
(vals[i].x.string.value.str= my_strndup(res->ptr(), res->length(),
MYF(MY_WME))))
(vals[i].x.string.value.str= sql_strmake(res->ptr(), res->length())))
{
vals[i].x.string.value.length= res->length();
vals[i].x.string.charset= res->charset();
@ -3975,26 +4017,12 @@ bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
}
if (vals[i].type != DYN_COL_NULL && args[valpos]->null_value)
{
if (vals[i].type == DYN_COL_STRING)
my_free(vals[i].x.string.value.str);
vals[i].type= DYN_COL_NULL;
}
}
return FALSE;
}
void Item_func_dyncol_create::cleanup_arguments()
{
uint column_count= (arg_count / 2);
uint i;
for (i= 0; i < column_count; i++)
{
if (vals[i].type == DYN_COL_STRING)
my_free(vals[i].x.string.value.str);
}
force_names= FALSE;
}
String *Item_func_dyncol_create::val_str(String *str)
{
@ -4011,8 +4039,11 @@ String *Item_func_dyncol_create::val_str(String *str)
}
else
{
if ((rc= dynamic_column_create_many_fmt(&col, column_count, keys,
vals, names || force_names)))
if ((rc= ((names || force_names) ?
mariadb_dyncol_create_many_named(&col, column_count, keys_str,
vals, TRUE) :
mariadb_dyncol_create_many(&col, column_count, keys_num,
vals, TRUE))))
{
dynamic_column_error_message(rc);
dynamic_column_column_free(&col);
@ -4024,7 +4055,7 @@ String *Item_func_dyncol_create::val_str(String *str)
/* Move result from DYNAMIC_COLUMN to str_value */
char *ptr;
size_t length, alloc_length;
dynamic_column_reassociate(&col, &ptr, &length, &alloc_length);
mariadb_dyncol_reassociate(&col, &ptr, &length, &alloc_length);
str_value.reassociate(ptr, (uint32) length, (uint32) alloc_length,
&my_charset_bin);
res= &str_value;
@ -4032,9 +4063,6 @@ String *Item_func_dyncol_create::val_str(String *str)
}
}
/* cleanup */
cleanup_arguments();
return res;
}
@ -4060,6 +4088,7 @@ void Item_func_dyncol_create::print_arguments(String *str,
case DYN_COL_DOUBLE:
str->append(STRING_WITH_LEN(" AS double"));
break;
case DYN_COL_DYNCOL:
case DYN_COL_STRING:
str->append(STRING_WITH_LEN(" AS char"));
if (defs[i].cs)
@ -4109,7 +4138,7 @@ String *Item_func_dyncol_json::val_str(String *str)
col.str= (char *)res->ptr();
col.length= res->length();
if ((rc= dynamic_column_json(&col, &json)))
if ((rc= mariadb_dyncol_json(&col, &json)))
{
dynamic_column_error_message(rc);
goto null;
@ -4150,15 +4179,17 @@ String *Item_func_dyncol_add::val_str(String *str)
col.length= res->length();
memcpy(col.str, res->ptr(), col.length);
if (prepare_arguments(dynamic_column_has_names(&col)))
if (prepare_arguments(mariadb_dyncol_has_names(&col)))
goto null;
if ((rc= dynamic_column_update_many_fmt(&col, column_count, keys,
vals, names || force_names)))
if ((rc= ((names || force_names) ?
mariadb_dyncol_update_many_named(&col, column_count,
keys_str, vals) :
mariadb_dyncol_update_many(&col, column_count,
keys_num, vals))))
{
dynamic_column_error_message(rc);
dynamic_column_column_free(&col);
cleanup_arguments();
goto null;
}
@ -4166,15 +4197,12 @@ String *Item_func_dyncol_add::val_str(String *str)
/* Move result from DYNAMIC_COLUMN to str */
char *ptr;
size_t length, alloc_length;
dynamic_column_reassociate(&col, &ptr, &length, &alloc_length);
mariadb_dyncol_reassociate(&col, &ptr, &length, &alloc_length);
str->reassociate(ptr, (uint32) length, (uint32) alloc_length,
&my_charset_bin);
null_value= FALSE;
}
/* cleanup */
cleanup_arguments();
return str;
null:
@ -4264,8 +4292,8 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp)
dyn_str.str= (char*) res->ptr();
dyn_str.length= res->length();
if ((rc= ((name == NULL) ?
dynamic_column_get(&dyn_str, (uint) num, val) :
dynamic_column_get_str(&dyn_str, name, val))))
mariadb_dyncol_get(&dyn_str, (uint) num, val) :
mariadb_dyncol_get_named(&dyn_str, name, val))))
{
dynamic_column_error_message(rc);
null_value= 1;
@ -4297,6 +4325,7 @@ String *Item_dyncol_get::val_str(String *str_result)
case DYN_COL_DOUBLE:
str_result->set_real(val.x.double_value, NOT_FIXED_DEC, &my_charset_latin1);
break;
case DYN_COL_DYNCOL:
case DYN_COL_STRING:
if ((char*) tmp.ptr() <= val.x.string.value.str &&
(char*) tmp.ptr() + tmp.length() >= val.x.string.value.str)
@ -4373,6 +4402,7 @@ longlong Item_dyncol_get::val_int()
return 0;
switch (val.type) {
case DYN_COL_DYNCOL:
case DYN_COL_NULL:
goto null;
case DYN_COL_UINT:
@ -4453,6 +4483,7 @@ double Item_dyncol_get::val_real()
return 0.0;
switch (val.type) {
case DYN_COL_DYNCOL:
case DYN_COL_NULL:
goto null;
case DYN_COL_UINT:
@ -4510,6 +4541,7 @@ my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value)
return NULL;
switch (val.type) {
case DYN_COL_DYNCOL:
case DYN_COL_NULL:
goto null;
case DYN_COL_UINT:
@ -4569,6 +4601,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
return 1; // Error
switch (val.type) {
case DYN_COL_DYNCOL:
case DYN_COL_NULL:
goto null;
case DYN_COL_INT:
@ -4631,7 +4664,8 @@ String *Item_func_dyncol_list::val_str(String *str)
{
uint i;
enum enum_dyncol_func_result rc;
DYNAMIC_ARRAY arr;
LEX_STRING *names= 0;
uint count;
DYNAMIC_COLUMN col;
String *res= args[0]->val_str(str);
@ -4640,37 +4674,37 @@ String *Item_func_dyncol_list::val_str(String *str)
col.length= res->length();
/* We do not change the string, so could do this trick */
col.str= (char *)res->ptr();
if ((rc= dynamic_column_list_str(&col, &arr)))
if ((rc= mariadb_dyncol_list_named(&col, &count, &names)))
{
bzero(&col, sizeof(col));
dynamic_column_error_message(rc);
for (i= 0; i < arr.elements; i++)
my_free(dynamic_element(&arr, i, LEX_STRING*)->str);
delete_dynamic(&arr);
goto null;
}
bzero(&col, sizeof(col));
/*
We estimate average name length as 10
*/
if (str->alloc(arr.elements * 13))
if (str->alloc(count * 13))
goto null;
str->length(0);
str->set_charset(&my_charset_utf8_general_ci);
for (i= 0; i < arr.elements; i++)
for (i= 0; i < count; i++)
{
LEX_STRING *name= dynamic_element(&arr, i, LEX_STRING *);
append_identifier(current_thd, str, name->str, name->length);
if (i < arr.elements - 1)
append_identifier(current_thd, str, names[i].str, names[i].length);
if (i < count - 1)
str->qs_append(',');
my_free(name->str);
}
null_value= FALSE;
delete_dynamic(&arr);
if (names)
my_free(names);
return str;
null:
null_value= TRUE;
if (names)
my_free(names);
return NULL;
}

View File

@ -1001,10 +1001,10 @@ class Item_func_dyncol_create: public Item_str_func
protected:
DYNCALL_CREATE_DEF *defs;
DYNAMIC_COLUMN_VALUE *vals;
uchar *keys;
uint *keys_num;
LEX_STRING *keys_str;
bool names, force_names;
bool prepare_arguments(bool force_names);
void cleanup_arguments();
void print_arguments(String *str, enum_query_type query_type);
public:
Item_func_dyncol_create(List<Item> &args, DYNCALL_CREATE_DEF *dfs);
@ -1013,6 +1013,7 @@ public:
const char *func_name() const{ return "column_create"; }
String *val_str(String *);
virtual void print(String *str, enum_query_type query_type);
virtual enum Functype functype() const { return DYNCOL; }
};
@ -1081,3 +1082,4 @@ public:
extern String my_empty_string;
#endif /* ITEM_STRFUNC_INCLUDED */

View File

@ -126,10 +126,7 @@ static SYMBOL symbols[] = {
{ "COLUMN_CHECK", SYM(COLUMN_CHECK_SYM)},
{ "COLUMN_CREATE", SYM(COLUMN_CREATE_SYM)},
{ "COLUMN_DELETE", SYM(COLUMN_DELETE_SYM)},
{ "COLUMN_EXISTS", SYM(COLUMN_EXISTS_SYM)},
{ "COLUMN_GET", SYM(COLUMN_GET_SYM)},
{ "COLUMN_JSON", SYM(COLUMN_JSON_SYM)},
{ "COLUMN_LIST", SYM(COLUMN_LIST_SYM)},
{ "COMMENT", SYM(COMMENT_SYM)},
{ "COMMIT", SYM(COMMIT_SYM)},
{ "COMMITTED", SYM(COMMITTED_SYM)},

View File

@ -885,10 +885,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token COLUMN_CHECK_SYM
%token COLUMN_CREATE_SYM
%token COLUMN_DELETE_SYM
%token COLUMN_EXISTS_SYM
%token COLUMN_GET_SYM
%token COLUMN_JSON_SYM
%token COLUMN_LIST_SYM
%token COLUMN_SYM /* SQL-2003-R */
%token COLUMN_NAME_SYM /* SQL-2003-N */
%token COMMENT_SYM
@ -8807,20 +8804,6 @@ function_call_nonkeyword:
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_EXISTS_SYM '(' expr ',' expr ')'
{
$$= new (YYTHD->mem_root) Item_func_dyncol_exists($3, $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_LIST_SYM '(' expr ')'
{
$$= new (YYTHD->mem_root) Item_func_dyncol_list($3);
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_CREATE_SYM '(' dyncall_create_list ')'
{
@ -8828,13 +8811,6 @@ function_call_nonkeyword:
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_JSON_SYM '(' expr ')'
{
$$= create_func_dyncol_json(YYTHD, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
|
COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
{
@ -12927,10 +12903,7 @@ keyword:
| COLUMN_CHECK_SYM {}
| COLUMN_CREATE_SYM {}
| COLUMN_DELETE_SYM {}
| COLUMN_EXISTS_SYM {}
| COLUMN_GET_SYM {}
| COLUMN_JSON_SYM {}
| COLUMN_LIST_SYM {}
| COMMENT_SYM {}
| COMMIT_SYM {}
| CONTAINS_SYM {}

View File

@ -13,9 +13,9 @@ SET(cassandra_sources
#INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS})
#INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift)
INCLUDE_DIRECTORIES(AFTER /usr/local/include/thrift)
#INCLUDE_DIRECTORIES(AFTER /home/buildbot/build/thrift-inst/include/thrift/)
INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/)
#INCLUDE_DIRECTORIES(AFTER /home/psergey/cassandra/thrift/include/thrift/)
#
STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})

View File

@ -89,7 +89,7 @@ ha_create_table_option cassandra_field_option_list[]=
/*
Collect all other columns as dynamic here,
the valid values are YES/NO, ON/OFF, 1/0.
The default is 0, that is true, yes, on.
The default is 0, that is false, no, off.
*/
HA_FOPTION_BOOL("DYNAMIC_COLUMN_STORAGE", dyncol_field, 0),
HA_FOPTION_END
@ -862,9 +862,37 @@ public:
/**
Converting dynamic columns types to/from casandra types
*/
/**
Check and initialize (if it is needed) string MEM_ROOT
*/
static void alloc_strings_memroot(MEM_ROOT *mem_root)
{
if (!alloc_root_inited(mem_root))
{
/*
The mem_root used to allocate UUID (of length 36 + \0) so make
appropriate allocated size
*/
init_alloc_root(mem_root,
(36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 +
ALLOC_ROOT_MIN_BLOCK_SIZE,
(36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 +
ALLOC_ROOT_MIN_BLOCK_SIZE);
}
}
static void free_strings_memroot(MEM_ROOT *mem_root)
{
if (alloc_root_inited(mem_root))
free_root(mem_root, MYF(0));
}
bool cassandra_to_dyncol_intLong(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
value->type= DYN_COL_INT;
#ifdef WORDS_BIGENDIAN
@ -881,7 +909,7 @@ bool dyncol_to_cassandraLong(DYNAMIC_COLUMN_VALUE *value,
{
longlong *tmp= (longlong *) buff;
enum enum_dyncol_func_result rc=
dynamic_column_val_long(tmp, value);
mariadb_dyncol_val_long(tmp, value);
if (rc < 0)
return true;
*cass_data_len= sizeof(longlong);
@ -897,7 +925,8 @@ bool dyncol_to_cassandraLong(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_intInt32(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
int32 tmp;
value->type= DYN_COL_INT;
@ -917,7 +946,7 @@ bool dyncol_to_cassandraInt32(DYNAMIC_COLUMN_VALUE *value,
{
longlong *tmp= (longlong *) ((char *)buff + sizeof(longlong));
enum enum_dyncol_func_result rc=
dynamic_column_val_long(tmp, value);
mariadb_dyncol_val_long(tmp, value);
if (rc < 0)
return true;
*cass_data_len= sizeof(int32);
@ -937,7 +966,8 @@ bool dyncol_to_cassandraInt32(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_intCounter(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
value->type= DYN_COL_INT;
value->x.long_value= *((longlong *)cass_data);
@ -951,7 +981,7 @@ bool dyncol_to_cassandraCounter(DYNAMIC_COLUMN_VALUE *value,
{
longlong *tmp= (longlong *)buff;
enum enum_dyncol_func_result rc=
dynamic_column_val_long(tmp, value);
mariadb_dyncol_val_long(tmp, value);
if (rc < 0)
return true;
*cass_data_len= sizeof(longlong);
@ -962,7 +992,8 @@ bool dyncol_to_cassandraCounter(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_doubleFloat(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
value->type= DYN_COL_DOUBLE;
value->x.double_value= *((float *)cass_data);
@ -975,7 +1006,7 @@ bool dyncol_to_cassandraFloat(DYNAMIC_COLUMN_VALUE *value,
{
double tmp;
enum enum_dyncol_func_result rc=
dynamic_column_val_double(&tmp, value);
mariadb_dyncol_val_double(&tmp, value);
if (rc < 0)
return true;
*((float *)buff)= (float) tmp;
@ -987,7 +1018,9 @@ bool dyncol_to_cassandraFloat(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_doubleDouble(const char *cass_data,
int cass_data_len __attribute__((unused)),
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root
__attribute__((unused)))
{
value->type= DYN_COL_DOUBLE;
value->x.double_value= *((double *)cass_data);
@ -1000,7 +1033,7 @@ bool dyncol_to_cassandraDouble(DYNAMIC_COLUMN_VALUE *value,
{
double *tmp= (double *)buff;
enum enum_dyncol_func_result rc=
dynamic_column_val_double(tmp, value);
mariadb_dyncol_val_double(tmp, value);
if (rc < 0)
return true;
*cass_data_len= sizeof(double);
@ -1018,7 +1051,6 @@ bool cassandra_to_dyncol_strStr(const char *cass_data,
value->x.string.charset= cs;
value->x.string.value.str= (char *)cass_data;
value->x.string.value.length= cass_data_len;
value->x.string.nonfreeable= TRUE; // do not try to free
return 0;
}
@ -1030,7 +1062,7 @@ bool dyncol_to_cassandraStr(DYNAMIC_COLUMN_VALUE *value,
if (init_dynamic_string(&tmp, NULL, 1024, 1024))
return 1;
enum enum_dyncol_func_result rc=
dynamic_column_val_str(&tmp, value, cs, FALSE);
mariadb_dyncol_val_str(&tmp, value, cs, '\0');
if (rc < 0)
{
dynstr_free(&tmp);
@ -1044,7 +1076,8 @@ bool dyncol_to_cassandraStr(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_strBytes(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value,
&my_charset_bin);
@ -1060,7 +1093,8 @@ bool dyncol_to_cassandraBytes(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_strAscii(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value,
&my_charset_latin1_bin);
@ -1076,7 +1110,8 @@ bool dyncol_to_cassandraAscii(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_strUTF8(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
return cassandra_to_dyncol_strStr(cass_data, cass_data_len, value,
&my_charset_utf8_unicode_ci);
@ -1092,20 +1127,20 @@ bool dyncol_to_cassandraUTF8(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_strUUID(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root)
{
value->type= DYN_COL_STRING;
value->x.string.charset= &my_charset_bin;
value->x.string.value.str= (char *)my_malloc(37, MYF(0));
alloc_strings_memroot(mem_root);
value->x.string.value.str= (char *)alloc_root(mem_root, 37);
if (!value->x.string.value.str)
{
value->x.string.value.length= 0;
value->x.string.nonfreeable= TRUE;
return 1;
}
convert_uuid2string(value->x.string.value.str, cass_data);
value->x.string.value.length= 36;
value->x.string.nonfreeable= FALSE;
return 0;
}
@ -1117,7 +1152,7 @@ bool dyncol_to_cassandraUUID(DYNAMIC_COLUMN_VALUE *value,
if (init_dynamic_string(&tmp, NULL, 1024, 1024))
return true;
enum enum_dyncol_func_result rc=
dynamic_column_val_str(&tmp, value, &my_charset_latin1_bin, FALSE);
mariadb_dyncol_val_str(&tmp, value, &my_charset_latin1_bin, '\0');
if (rc < 0 || tmp.length != 36 || convert_string2uuid((char *)buff, tmp.str))
{
dynstr_free(&tmp);
@ -1132,7 +1167,8 @@ bool dyncol_to_cassandraUUID(DYNAMIC_COLUMN_VALUE *value,
bool cassandra_to_dyncol_intBool(const char *cass_data,
int cass_data_len,
DYNAMIC_COLUMN_VALUE *value)
DYNAMIC_COLUMN_VALUE *value,
MEM_ROOT *mem_root __attribute__((unused)))
{
value->type= DYN_COL_INT;
value->x.long_value= (cass_data[0] ? 1 : 0);
@ -1145,7 +1181,7 @@ bool dyncol_to_cassandraBool(DYNAMIC_COLUMN_VALUE *value,
{
longlong tmp;
enum enum_dyncol_func_result rc=
dynamic_column_val_long(&tmp, value);
mariadb_dyncol_val_long(&tmp, value);
if (rc < 0)
return true;
((char *)buff)[0]= (tmp ? 1 : 0);
@ -1430,10 +1466,7 @@ bool ha_cassandra::setup_field_converters(Field **field_arg, uint n_fields)
(CASSANDRA_TYPE_DEF *)(field_converters + n_fields);
special_type_field_names=
((LEX_STRING*)(special_type_field_converters + max_non_default_fields));
}
if (dyncol_set)
{
if (init_dynamic_array(&dynamic_values,
sizeof(DYNAMIC_COLUMN_VALUE),
DYNCOL_USUAL, DYNCOL_DELTA))
@ -1667,14 +1700,6 @@ void ha_cassandra::print_conversion_error(const char *field_name,
}
void free_strings(DYNAMIC_COLUMN_VALUE *vals, uint num)
{
for (uint i= 0; i < num; i++)
if (vals[i].type == DYN_COL_STRING &&
!vals[i].x.string.nonfreeable)
my_free(vals[i].x.string.value.str);
}
CASSANDRA_TYPE_DEF * ha_cassandra::get_cassandra_field_def(char *cass_name,
int cass_name_len)
@ -1695,6 +1720,7 @@ CASSANDRA_TYPE_DEF * ha_cassandra::get_cassandra_field_def(char *cass_name,
int ha_cassandra::read_cassandra_columns(bool unpack_pk)
{
MEM_ROOT strings_root;
char *cass_name;
char *cass_value;
int cass_value_len, cass_name_len;
@ -1702,6 +1728,7 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk)
int res= 0;
ulong total_name_len= 0;
clear_alloc_root(&strings_root);
/*
cassandra_to_mariadb() calls will use field->store(...) methods, which
require that the column is in the table->write_set
@ -1770,7 +1797,8 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk)
}
if ((res= (*(type->cassandra_to_dynamic))(cass_value,
cass_value_len, &val)) ||
cass_value_len, &val,
&strings_root)) ||
insert_dynamic(&dynamic_names, (uchar *) &nm) ||
insert_dynamic(&dynamic_values, (uchar *) &val))
{
@ -1778,10 +1806,9 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk)
{
print_conversion_error(cass_name, cass_value, cass_value_len);
}
free_strings((DYNAMIC_COLUMN_VALUE *)dynamic_values.buffer,
dynamic_values.elements);
free_strings_memroot(&strings_root);
// EOM shouldm be already reported if happened
res=1;
res= 1;
goto err;
}
}
@ -1790,21 +1817,17 @@ int ha_cassandra::read_cassandra_columns(bool unpack_pk)
dynamic_rec.length= 0;
if (dyncol_set)
{
if (dynamic_column_create_many_internal_fmt(&dynamic_rec,
if (mariadb_dyncol_create_many_named(&dynamic_rec,
dynamic_names.elements,
dynamic_names.buffer,
(LEX_STRING *)dynamic_names.buffer,
(DYNAMIC_COLUMN_VALUE *)
dynamic_values.buffer,
FALSE,
TRUE) < 0)
FALSE) < 0)
dynamic_rec.length= 0;
free_strings((DYNAMIC_COLUMN_VALUE *)dynamic_values.buffer,
dynamic_values.elements);
free_strings_memroot(&strings_root);
dynamic_values.elements= dynamic_names.elements= 0;
}
if (dyncol_set)
{
if (dynamic_rec.length == 0)
table->field[dyncol_field]->set_null();
else
@ -1836,11 +1859,14 @@ err:
return res;
}
int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names,
String *valcol, char **freenames)
int ha_cassandra::read_dyncol(uint *count,
DYNAMIC_COLUMN_VALUE **vals,
LEX_STRING **names,
String *valcol)
{
String *strcol;
DYNAMIC_COLUMN col;
enum enum_dyncol_func_result rc;
DBUG_ENTER("ha_cassandra::read_dyncol");
@ -1850,8 +1876,9 @@ int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names,
strcol= field->val_str(NULL, valcol);
if (field->is_null())
{
bzero(vals, sizeof(DYNAMIC_ARRAY));
bzero(names, sizeof(DYNAMIC_ARRAY));
*count= 0;
*names= 0;
*vals= 0;
DBUG_RETURN(0); // nothing to write
}
/*
@ -1861,7 +1888,7 @@ int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names,
bzero(&col, sizeof(col));
col.str= (char *)strcol->ptr();
col.length= strcol->length();
if ((rc= dynamic_column_vals(&col, names, vals, freenames)) < 0)
if ((rc= mariadb_dyncol_unpack(&col, count, names, vals)) < 0)
{
dynamic_column_error_message(rc);
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
@ -1869,34 +1896,33 @@ int ha_cassandra::read_dyncol(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names,
DBUG_RETURN(0);
}
int ha_cassandra::write_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names)
int ha_cassandra::write_dynamic_row(uint count,
DYNAMIC_COLUMN_VALUE *vals,
LEX_STRING *names)
{
uint i;
DBUG_ENTER("ha_cassandra::write_dynamic_row");
DBUG_ASSERT(dyncol_set);
DBUG_ASSERT(names->elements == vals->elements);
for (i= 0; i < names->elements; i++)
for (i= 0; i < count; i++)
{
char buff[16];
CASSANDRA_TYPE_DEF *type;
void *freemem= NULL;
char *cass_data;
int cass_data_len;
LEX_STRING *name= dynamic_element(names, i, LEX_STRING*);
DYNAMIC_COLUMN_VALUE *val= dynamic_element(vals, i, DYNAMIC_COLUMN_VALUE*);
DBUG_PRINT("info", ("field %*s", (int)name->length, name->str));
type= get_cassandra_field_def(name->str, (int) name->length);
if ((*type->dynamic_to_cassandra)(val, &cass_data, &cass_data_len,
DBUG_PRINT("info", ("field %*s", (int)names[i].length, names[i].str));
type= get_cassandra_field_def(names[i].str, (int) names[i].length);
if ((*type->dynamic_to_cassandra)(vals +i, &cass_data, &cass_data_len,
buff, &freemem))
{
my_error(ER_WARN_DATA_OUT_OF_RANGE, MYF(0),
name->str, insert_lineno);
DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
names[i].str, insert_lineno);
DBUG_RETURN(HA_ERR_GENERIC);
}
se->add_insert_column(name->str, name->length,
se->add_insert_column(names[i].str, names[i].length,
cass_data, cass_data_len);
if (freemem)
my_free(freemem);
@ -1904,13 +1930,19 @@ int ha_cassandra::write_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names)
DBUG_RETURN(0);
}
void ha_cassandra::free_dynamic_row(DYNAMIC_ARRAY *vals, DYNAMIC_ARRAY *names,
char *free_names)
void ha_cassandra::free_dynamic_row(DYNAMIC_COLUMN_VALUE **vals,
LEX_STRING **names)
{
delete_dynamic(names);
delete_dynamic(vals);
if (free_names)
my_free(free_names);
if (*vals)
{
my_free(*vals);
*vals= 0;
}
if (*names)
{
my_free(*names);
*names= 0;
}
}
int ha_cassandra::write_row(uchar *buf)
@ -1949,13 +1981,14 @@ int ha_cassandra::write_row(uchar *buf)
if (dyncol_set && dyncol_field == i)
{
String valcol;
DYNAMIC_ARRAY vals, names;
char *free_names= NULL;
DYNAMIC_COLUMN_VALUE *vals;
LEX_STRING *names;
uint count;
int rc;
DBUG_ASSERT(field_converters[i] == NULL);
if (!(rc= read_dyncol(&vals, &names, &valcol, &free_names)))
rc= write_dynamic_row(&vals, &names);
free_dynamic_row(&vals, &names, free_names);
if (!(rc= read_dyncol(&count, &vals, &names, &valcol)))
rc= write_dynamic_row(count, vals, names);
free_dynamic_row(&vals, &names);
if (rc)
{
dbug_tmp_restore_column_map(table->read_set, old_map);
@ -2336,9 +2369,10 @@ public:
int ha_cassandra::update_row(const uchar *old_data, uchar *new_data)
{
DYNAMIC_ARRAY oldvals, oldnames, vals, names;
DYNAMIC_COLUMN_VALUE *oldvals, *vals;
LEX_STRING *oldnames, *names;
uint oldcount, count;
String oldvalcol, valcol;
char *oldfree_names= NULL, *free_names= NULL;
my_bitmap_map *old_map;
int res;
DBUG_ENTER("ha_cassandra::update_row");
@ -2381,12 +2415,12 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data)
my_ptrdiff_t diff;
diff= (my_ptrdiff_t) (old_data - new_data);
field->move_field_offset(diff); // Points now at old_data
if ((res= read_dyncol(&oldvals, &oldnames, &oldvalcol, &oldfree_names)))
if ((res= read_dyncol(&oldcount, &oldvals, &oldnames, &oldvalcol)))
DBUG_RETURN(res);
field->move_field_offset(-diff); // back to new_data
if ((res= read_dyncol(&vals, &names, &valcol, &free_names)))
if ((res= read_dyncol(&count, &vals, &names, &valcol)))
{
free_dynamic_row(&oldnames, &oldvals, oldfree_names);
free_dynamic_row(&oldvals, &oldnames);
DBUG_RETURN(res);
}
}
@ -2399,9 +2433,9 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data)
*/
Column_name_enumerator_impl name_enumerator(this);
se->add_row_deletion(old_key, old_key_len, &name_enumerator,
(LEX_STRING *)oldnames.buffer,
(dyncol_set ? oldnames.elements : 0));
oldnames.elements= oldvals.elements= 0; // they will be deleted
oldnames,
(dyncol_set ? oldcount : 0));
oldcount= 0; // they will be deleted
}
se->start_row_insert(new_key, new_key_len);
@ -2414,7 +2448,7 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data)
if (dyncol_set && dyncol_field == i)
{
DBUG_ASSERT(field_converters[i] == NULL);
if ((res= write_dynamic_row(&vals, &names)))
if ((res= write_dynamic_row(count, vals, names)))
goto err;
}
else
@ -2434,24 +2468,19 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data)
{
/* find removed fields */
uint i= 0, j= 0;
LEX_STRING *onames= (LEX_STRING *)oldnames.buffer;
LEX_STRING *nnames= (LEX_STRING *)names.buffer;
/* both array are sorted */
for(; i < oldnames.elements; i++)
for(; i < oldcount; i++)
{
int scmp= 0;
while (j < names.elements &&
(nnames[j].length < onames[i].length ||
(nnames[j].length == onames[i].length &&
(scmp= memcmp(nnames[j].str, onames[i].str,
onames[i].length)) < 0)))
while (j < count &&
(scmp = mariadb_dyncol_column_cmp_named(names + j,
oldnames + i)) < 0)
j++;
if (j < names.elements &&
nnames[j].length == onames[i].length &&
if (j < count &&
scmp == 0)
j++;
else
se->add_insert_delete_column(onames[i].str, onames[i].length);
se->add_insert_delete_column(oldnames[i].str, oldnames[i].length);
}
}
@ -2465,8 +2494,8 @@ int ha_cassandra::update_row(const uchar *old_data, uchar *new_data)
err:
if (dyncol_set)
{
free_dynamic_row(&oldnames, &oldvals, oldfree_names);
free_dynamic_row(&names, &vals, free_names);
free_dynamic_row(&oldvals, &oldnames);
free_dynamic_row(&vals, &names);
}
DBUG_RETURN(res? HA_ERR_INTERNAL_ERROR: 0);

View File

@ -37,6 +37,8 @@ typedef struct st_cassandra_share {
} CASSANDRA_SHARE;
class ColumnDataConverter;
struct st_dynamic_column_value;
typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;
struct ha_table_option_struct;
@ -45,7 +47,8 @@ struct st_dynamic_column_value;
typedef bool (* CAS2DYN_CONVERTER)(const char *cass_data,
int cass_data_len,
struct st_dynamic_column_value *value);
struct st_dynamic_column_value *value,
MEM_ROOT *mem_root);
typedef bool (* DYN2CAS_CONVERTER)(struct st_dynamic_column_value *value,
char **cass_data,
int *cass_data_len,
@ -227,11 +230,14 @@ private:
bool source_exhausted;
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);
int read_dyncol(uint *count,
DYNAMIC_COLUMN_VALUE **vals, LEX_STRING **names,
String *valcol);
int write_dynamic_row(uint count,
DYNAMIC_COLUMN_VALUE *vals,
LEX_STRING *names);
void static free_dynamic_row(DYNAMIC_COLUMN_VALUE **vals,
LEX_STRING **names);
CASSANDRA_TYPE_DEF * get_cassandra_field_def(char *cass_name,
int cass_name_length);
public: