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:
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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';
|
||||
|
@ -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
@ -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;
|
||||
|
1257
mysys/ma_dyncol.c
1257
mysys/ma_dyncol.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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)},
|
||||
|
@ -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 {}
|
||||
|
@ -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})
|
||||
|
@ -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,8 +1806,7 @@ 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;
|
||||
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);
|
||||
|
@ -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:
|
||||
|
Reference in New Issue
Block a user