MDEV-377 Name support for dynamic columns
MDEV-127 Optimization of memory allocation MDEV-483 Make column_check function which cheсks dynamic columns integrit JSON conversion function
This commit is contained in:
parent
4db207d56d
commit
7327cd9717
@ -102,6 +102,13 @@ dynamic_column_create_many(DYNAMIC_COLUMN *str,
|
||||
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_update(DYNAMIC_COLUMN *org, uint column_nr,
|
||||
DYNAMIC_COLUMN_VALUE *value);
|
||||
@ -110,16 +117,30 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str,
|
||||
uint add_column_count,
|
||||
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);
|
||||
enum enum_dyncol_func_result
|
||||
dynamic_column_exists_fmt(DYNAMIC_COLUMN *str, void *key, my_bool string_keys);
|
||||
|
||||
/* List of not NULL columns */
|
||||
enum enum_dyncol_func_result
|
||||
dynamic_column_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);
|
||||
|
||||
/*
|
||||
if the column do not exists it is NULL
|
||||
@ -127,6 +148,17 @@ dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint);
|
||||
enum enum_dyncol_func_result
|
||||
dynamic_column_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,
|
||||
DYNAMIC_COLUMN_VALUE *store_it_here);
|
||||
|
||||
my_bool dynamic_column_has_names(DYNAMIC_COLUMN *str);
|
||||
|
||||
enum enum_dyncol_func_result
|
||||
dynamic_column_check(DYNAMIC_COLUMN *str);
|
||||
|
||||
enum enum_dyncol_func_result
|
||||
dynamic_column_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)
|
||||
|
@ -793,12 +793,18 @@ my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
|
||||
size_t length);
|
||||
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);
|
||||
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 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,
|
||||
CHARSET_INFO *to_cs,
|
||||
const char *from, uint32 from_length,
|
||||
CHARSET_INFO *from_cs, uint *errors);
|
||||
#ifdef HAVE_MLOCK
|
||||
extern void *my_malloc_lock(size_t length,myf flags);
|
||||
extern void my_free_lock(void *ptr);
|
||||
|
@ -1088,7 +1088,7 @@ column_list(column_add(column_create(1, 1), 1, null))
|
||||
|
||||
select column_list(column_add(column_create(1, 1), 1, ""));
|
||||
column_list(column_add(column_create(1, 1), 1, ""))
|
||||
1
|
||||
`1`
|
||||
select hex(column_add("", 1, 1));
|
||||
hex(column_add("", 1, 1))
|
||||
00010001000002
|
||||
@ -1133,10 +1133,10 @@ column_exists(column_create(1, 1212 as integer, 2, 1212 as integer), 4)
|
||||
# column list
|
||||
select column_list(column_create(1, 1212 as integer, 2, 1212 as integer));
|
||||
column_list(column_create(1, 1212 as integer, 2, 1212 as integer))
|
||||
1,2
|
||||
`1`,`2`
|
||||
select column_list(column_create(1, 1212 as integer));
|
||||
column_list(column_create(1, 1212 as integer))
|
||||
1
|
||||
`1`
|
||||
select column_list(column_create(1, NULL as integer));
|
||||
column_list(column_create(1, NULL as integer))
|
||||
|
||||
@ -1218,35 +1218,35 @@ sum(column_get(str, 1 as int))
|
||||
11
|
||||
select id, column_list(str) from t1 where id= 5;
|
||||
id column_list(str)
|
||||
5 1,2,3,10
|
||||
5 `1`,`2`,`3`,`10`
|
||||
update t1 set str=column_delete(str, 3, 4, 2) where id= 5;
|
||||
select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1;
|
||||
id length(str) column_list(str) column_get(str, 1 as int) column_get(str, 2 as char) column_get(str, 3 as int)
|
||||
1 12 1,2 1 a NULL
|
||||
2 12 1,2 2 a NULL
|
||||
3 12 2,3 NULL c 100
|
||||
4 16 1,2,3 5 c 100
|
||||
5 15 1,10 6 NULL NULL
|
||||
6 21 2,3,10 NULL c 100
|
||||
1 12 `1`,`2` 1 a NULL
|
||||
2 12 `1`,`2` 2 a NULL
|
||||
3 12 `2`,`3` NULL c 100
|
||||
4 16 `1`,`2`,`3` 5 c 100
|
||||
5 15 `1`,`10` 6 NULL NULL
|
||||
6 21 `2`,`3`,`10` NULL c 100
|
||||
update t1 set str=column_add(str, 4, 45 as char, 2, 'c') where id= 5;
|
||||
select id, length(str), column_list(str), column_get(str, 1 as int), column_get(str, 2 as char), column_get(str, 3 as int) from t1 where id = 5;
|
||||
id length(str) column_list(str) column_get(str, 1 as int) column_get(str, 2 as char) column_get(str, 3 as int)
|
||||
5 26 1,2,4,10 6 c NULL
|
||||
5 26 `1`,`2`,`4`,`10` 6 c NULL
|
||||
select id, length(str), column_list(str), column_exists(str, 4) from t1;
|
||||
id length(str) column_list(str) column_exists(str, 4)
|
||||
1 12 1,2 0
|
||||
2 12 1,2 0
|
||||
3 12 2,3 0
|
||||
4 16 1,2,3 0
|
||||
5 26 1,2,4,10 1
|
||||
6 21 2,3,10 0
|
||||
1 12 `1`,`2` 0
|
||||
2 12 `1`,`2` 0
|
||||
3 12 `2`,`3` 0
|
||||
4 16 `1`,`2`,`3` 0
|
||||
5 26 `1`,`2`,`4`,`10` 1
|
||||
6 21 `2`,`3`,`10` 0
|
||||
select sum(column_get(str, 1 as int)), column_list(str) from t1 group by 2;
|
||||
sum(column_get(str, 1 as int)) column_list(str)
|
||||
3 1,2
|
||||
5 1,2,3
|
||||
6 1,2,4,10
|
||||
NULL 2,3
|
||||
NULL 2,3,10
|
||||
3 `1`,`2`
|
||||
5 `1`,`2`,`3`
|
||||
6 `1`,`2`,`4`,`10`
|
||||
NULL `2`,`3`
|
||||
NULL `2`,`3`,`10`
|
||||
select id, hex(str) from t1;
|
||||
id hex(str)
|
||||
1 00020001000002000B020861
|
||||
@ -1282,11 +1282,11 @@ id
|
||||
5
|
||||
select id, column_list(str), length(str) from t1 where id=5;
|
||||
id column_list(str) length(str)
|
||||
5 1,2,4,5,10 100048
|
||||
5 `1`,`2`,`4`,`5`,`10` 100048
|
||||
update t1 set str=column_delete(str, 5) where id=5;
|
||||
select id, column_list(str), length(str) from t1 where id=5;
|
||||
id column_list(str) length(str)
|
||||
5 1,2,4,10 34
|
||||
5 `1`,`2`,`4`,`10` 34
|
||||
drop table t1;
|
||||
#
|
||||
# LP#778905: Assertion `value->year <= 9999' failed in
|
||||
@ -1306,7 +1306,7 @@ INSERT INTO t1 SET f1 = COLUMN_CREATE( 2 , 'cde' );
|
||||
SELECT HEX(COLUMN_ADD(f1, 1, 'abc')), COLUMN_LIST(f1) FROM t1;
|
||||
HEX(COLUMN_ADD(f1, 1, 'abc')) COLUMN_LIST(f1)
|
||||
NULL NULL
|
||||
0002000100030200230861626308636465 2
|
||||
0002000100030200230861626308636465 `2`
|
||||
SELECT COLUMN_ADD(f1, 1, 'abc'), COLUMN_LIST(f1) FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
@ -1335,3 +1335,245 @@ hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal))
|
||||
select hex(COLUMN_CREATE(0, 0.0 as decimal));
|
||||
hex(COLUMN_CREATE(0, 0.0 as decimal))
|
||||
000100000004
|
||||
#
|
||||
# test of symbolic names
|
||||
#
|
||||
# creation test (names)
|
||||
set names utf8;
|
||||
select hex(column_create("адын", 1212));
|
||||
hex(column_create("адын", 1212))
|
||||
040100080008000000D0B0D0B4D18BD0BD7809
|
||||
select hex(column_create("1212", 1212));
|
||||
hex(column_create("1212", 1212))
|
||||
040100040004000000313231327809
|
||||
select hex(column_create(1212, 2, "www", 3));
|
||||
hex(column_create(1212, 2, "www", 3))
|
||||
04020007000300000004030008777777313231320604
|
||||
select hex(column_create("1212", 2, "www", 3));
|
||||
hex(column_create("1212", 2, "www", 3))
|
||||
04020007000300000004030008777777313231320604
|
||||
select hex(column_create("1212", 2, 3, 3));
|
||||
hex(column_create("1212", 2, 3, 3))
|
||||
0402000500010000000401000833313231320604
|
||||
select hex(column_create("1212", 2, "адын", 1, 3, 3));
|
||||
hex(column_create("1212", 2, "адын", 1, 3, 3))
|
||||
0403000D000100000004010008080500103331323132D0B0D0B4D18BD0BD060402
|
||||
set names default;
|
||||
# fetching column test (names)
|
||||
set names utf8;
|
||||
select column_get(column_create("адын", 1212), "адын" as int);
|
||||
column_get(column_create("адын", 1212), "адын" as int)
|
||||
1212
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int);
|
||||
column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int)
|
||||
1
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int);
|
||||
column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int)
|
||||
2
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int);
|
||||
column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int)
|
||||
3
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int);
|
||||
column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int)
|
||||
3
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int);
|
||||
column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int)
|
||||
NULL
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int);
|
||||
column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int)
|
||||
NULL
|
||||
set names default;
|
||||
# column existance test (names)
|
||||
set names utf8;
|
||||
select column_exists(column_create("адын", 1212), "адын");
|
||||
column_exists(column_create("адын", 1212), "адын")
|
||||
1
|
||||
select column_exists(column_create("адын", 1212), "aады");
|
||||
column_exists(column_create("адын", 1212), "aады")
|
||||
0
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын");
|
||||
column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын")
|
||||
1
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212);
|
||||
column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212)
|
||||
1
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3");
|
||||
column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3")
|
||||
1
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3);
|
||||
column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3)
|
||||
1
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4);
|
||||
column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4)
|
||||
0
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4");
|
||||
column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4")
|
||||
0
|
||||
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
|
||||
select hex(column_add(column_create("1", "AAA"), "b", "BBB"));
|
||||
hex(column_add(column_create("1", "AAA"), "b", "BBB"))
|
||||
0402000200010000030101002331620841414108424242
|
||||
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
|
||||
select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char);
|
||||
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
|
||||
select hex(column_add(column_create("a", "AAA"), "1", "BBB"));
|
||||
hex(column_add(column_create("a", "AAA"), "1", "BBB"))
|
||||
0402000200010000030101002331610842424208414141
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer);
|
||||
column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" 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
|
||||
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
|
||||
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
|
||||
select hex(column_add(column_create("a", 1), "a", null));
|
||||
hex(column_add(column_create("a", 1), "a", null))
|
||||
0400000000
|
||||
select column_list(column_add(column_create("a", 1), "a", null));
|
||||
column_list(column_add(column_create("a", 1), "a", null))
|
||||
|
||||
select column_list(column_add(column_create("a", 1), "a", ""));
|
||||
column_list(column_add(column_create("a", 1), "a", ""))
|
||||
`a`
|
||||
select hex(column_add("", "a", 1));
|
||||
hex(column_add("", "a", 1))
|
||||
0401000100010000006102
|
||||
# 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e"));
|
||||
hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e"))
|
||||
0400000000
|
||||
select hex(column_delete(column_create("a", 1), "a"));
|
||||
hex(column_delete(column_create("a", 1), "a"))
|
||||
0400000000
|
||||
select hex(column_delete("", "a"));
|
||||
hex(column_delete("", "a"))
|
||||
|
||||
#
|
||||
# MDEV-458 DNAMES: Server crashes on using an unquoted string
|
||||
# as a dynamic column name
|
||||
#
|
||||
select COLUMN_CREATE(color, "black");
|
||||
ERROR 42S22: Unknown column 'color' in 'field list'
|
||||
#
|
||||
# MDEV-489 Assertion `offset < 0x1f' failed in
|
||||
# type_and_offset_store on COLUMN_ADD
|
||||
#
|
||||
CREATE TABLE t1 (f1 tinyblob);
|
||||
INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30)));
|
||||
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' );
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'f1' at row 1
|
||||
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' );
|
||||
ERROR HY000: Encountered illegal format of dynamic column string
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-490/MDEV-491 null as arguments
|
||||
#
|
||||
SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR );
|
||||
COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR )
|
||||
NULL
|
||||
SELECT COLUMN_GET( NULL, 'col' as char );
|
||||
COLUMN_GET( NULL, 'col' as char )
|
||||
NULL
|
||||
SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL);
|
||||
COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL)
|
||||
NULL
|
||||
SELECT COLUMN_EXISTS( NULL, 'col');
|
||||
COLUMN_EXISTS( NULL, 'col')
|
||||
NULL
|
||||
SELECT COLUMN_CREATE( NULL, 'val' );
|
||||
COLUMN_CREATE( NULL, 'val' )
|
||||
NULL
|
||||
SELECT COLUMN_ADD( NULL, 'val', 'col');
|
||||
COLUMN_ADD( NULL, 'val', 'col')
|
||||
NULL
|
||||
#
|
||||
# MDEV-488: Assertion `column_name->length < 255' failed on a
|
||||
# column name with length 255 (precisely)
|
||||
#
|
||||
SELECT hex(COLUMN_CREATE(REPEAT('a',255),1));
|
||||
hex(COLUMN_CREATE(REPEAT('a',255),1))
|
||||
040100FF00FF00000061616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616102
|
||||
SELECT hex(COLUMN_CREATE(REPEAT('a',256),1));
|
||||
ERROR 22007: Illegal value used as argument of dynamic column function
|
||||
#
|
||||
# JSON conversion
|
||||
#
|
||||
select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date));
|
||||
column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001"
|
||||
[{"int":-1212},{"date":"2011-04-05"},{"time":"00:45:49.000001"},{"uint":12334},{"double":"1.23444e+50"},{"string":"gdgd\\dhdjh\"dhdhd"},{"decimal":23.344},{"datetime":"2011-04-05 00:45:49.000001"}]
|
||||
select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date));
|
||||
column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date))
|
||||
[{"1":-1212},{"2":12334},{"3":23.344},{"4":"1.23444e+50"},{"5":"gdgd\\dhdjh\"dhdhd"},{"6":"00:45:49.000001"},{"7":"2011-04-05 00:45:49.000001"},{"8":"2011-04-05"}]
|
||||
#
|
||||
# CHECK test
|
||||
#
|
||||
SELECT COLUMN_CHECK(COLUMN_CREATE(1,'a'));
|
||||
COLUMN_CHECK(COLUMN_CREATE(1,'a'))
|
||||
1
|
||||
SELECT COLUMN_CHECK('abracadabra');
|
||||
COLUMN_CHECK('abracadabra')
|
||||
0
|
||||
SELECT COLUMN_CHECK('');
|
||||
COLUMN_CHECK('')
|
||||
1
|
||||
SELECT COLUMN_CHECK(NULL);
|
||||
COLUMN_CHECK(NULL)
|
||||
NULL
|
||||
|
@ -550,3 +550,125 @@ select hex(COLUMN_CREATE(0, COLUMN_GET(@a, 9 AS DECIMAL(19,0))));
|
||||
|
||||
select hex(COLUMN_CREATE(0, COLUMN_GET(COLUMN_CREATE(0, 0.0 as decimal), 0 as decimal)));
|
||||
select hex(COLUMN_CREATE(0, 0.0 as decimal));
|
||||
|
||||
--echo #
|
||||
--echo # test of symbolic names
|
||||
--echo #
|
||||
--echo # creation test (names)
|
||||
set names utf8;
|
||||
select hex(column_create("адын", 1212));
|
||||
select hex(column_create("1212", 1212));
|
||||
select hex(column_create(1212, 2, "www", 3));
|
||||
select hex(column_create("1212", 2, "www", 3));
|
||||
select hex(column_create("1212", 2, 3, 3));
|
||||
select hex(column_create("1212", 2, "адын", 1, 3, 3));
|
||||
set names default;
|
||||
|
||||
--echo # fetching column test (names)
|
||||
set names utf8;
|
||||
select column_get(column_create("адын", 1212), "адын" as int);
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), "адын" as int);
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), 1212 as int);
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), "3" as int);
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), 3 as int);
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), 4 as int);
|
||||
select column_get(column_create("1212", 2, "адын", 1, 3, 3), "4" as int);
|
||||
set names default;
|
||||
|
||||
--echo # column existance test (names)
|
||||
set names utf8;
|
||||
select column_exists(column_create("адын", 1212), "адын");
|
||||
select column_exists(column_create("адын", 1212), "aады");
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "адын");
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 1212);
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "3");
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 3);
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), 4);
|
||||
select column_exists(column_create("1212", 2, "адын", 1, 3, 3), "4");
|
||||
set names default;
|
||||
|
||||
--echo # column changing test (names)
|
||||
select hex(column_add(column_create(1, "AAA"), "b", "BBB"));
|
||||
select hex(column_add(column_create("1", "AAA"), "b", "BBB"));
|
||||
select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), 1 as char);
|
||||
select column_get(column_add(column_create(1, "AAA"), "b", "BBB"), "b" as char);
|
||||
select hex(column_add(column_create("a", "AAA"), 1, "BBB"));
|
||||
select hex(column_add(column_create("a", "AAA"), "1", "BBB"));
|
||||
select hex(column_add(column_create("a", 1212 as integer), "b", "1212" as integer));
|
||||
select hex(column_add(column_create("a", 1212 as integer), "a", "1212" as integer));
|
||||
select hex(column_add(column_create("a", 1212 as integer), "a", NULL as integer));
|
||||
select hex(column_add(column_create("a", 1212 as integer), "b", NULL as integer));
|
||||
select hex(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer));
|
||||
select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "a" as integer);
|
||||
select column_get(column_add(column_create("a", 1212 as integer), "b", 1212 as integer, "a", 11 as integer), "b" as integer);
|
||||
select hex(column_add(column_create("a", 1212 as integer), "a", 1212 as integer, "b", 11 as integer));
|
||||
select hex(column_add(column_create("a", NULL as integer), "a", 1212 as integer, "b", 11 as integer));
|
||||
select hex(column_add(column_create("a", 1212 as integer, "b", 1212 as integer), "a", 11 as integer));
|
||||
select hex(column_add(column_create("a", 1), "a", null));
|
||||
select column_list(column_add(column_create("a", 1), "a", null));
|
||||
select column_list(column_add(column_create("a", 1), "a", ""));
|
||||
select hex(column_add("", "a", 1));
|
||||
|
||||
-- echo # column delete (names)
|
||||
select hex(column_delete(column_create("a", 1212 as integer, "b", 1212 as integer), "a"));
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b"));
|
||||
select hex(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer));
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "c"));
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "d"));
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "a"));
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "b", "c"));
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c"));
|
||||
select hex(column_delete(column_create("a", 1 as integer, "b", 2 as integer, "c", 3 as integer), "a", "b", "c", "e"));
|
||||
select hex(column_delete(column_create("a", 1), "a"));
|
||||
select hex(column_delete("", "a"));
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-458 DNAMES: Server crashes on using an unquoted string
|
||||
--echo # as a dynamic column name
|
||||
--echo #
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
select COLUMN_CREATE(color, "black");
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-489 Assertion `offset < 0x1f' failed in
|
||||
--echo # type_and_offset_store on COLUMN_ADD
|
||||
--echo #
|
||||
CREATE TABLE t1 (f1 tinyblob);
|
||||
|
||||
INSERT INTO t1 VALUES (COLUMN_CREATE('col1', REPEAT('a',30)));
|
||||
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('b',211), 'val2' );
|
||||
--error ER_DYN_COL_WRONG_FORMAT
|
||||
UPDATE t1 SET f1 = COLUMN_ADD( f1, REPEAT('c',211), 'val3' );
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-490/MDEV-491 null as arguments
|
||||
--echo #
|
||||
SELECT COLUMN_GET( COLUMN_CREATE( 'col', 'val' ), NULL AS CHAR );
|
||||
SELECT COLUMN_GET( NULL, 'col' as char );
|
||||
SELECT COLUMN_EXISTS( COLUMN_CREATE( 'col', 'val' ), NULL);
|
||||
SELECT COLUMN_EXISTS( NULL, 'col');
|
||||
SELECT COLUMN_CREATE( NULL, 'val' );
|
||||
SELECT COLUMN_ADD( NULL, 'val', 'col');
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-488: Assertion `column_name->length < 255' failed on a
|
||||
--echo # column name with length 255 (precisely)
|
||||
--echo #
|
||||
SELECT hex(COLUMN_CREATE(REPEAT('a',255),1));
|
||||
--error ER_DYN_COL_DATA
|
||||
SELECT hex(COLUMN_CREATE(REPEAT('a',256),1));
|
||||
|
||||
--echo #
|
||||
--echo # JSON conversion
|
||||
--echo #
|
||||
select column_json(column_create("int", -1212 as int, "uint", 12334 as unsigned int, "decimal", "23.344" as decimal, "double", 1.23444e50 as double, "string", 'gdgd\\dhdjh"dhdhd' as char, "time", "0:45:49.000001" AS time, "datetime", "2011-04-05 0:45:49.000001" AS datetime, "date", "2011-04-05" AS date));
|
||||
select column_json(column_create(1, -1212 as int, 2, 12334 as unsigned int, 3, "23.344" as decimal, 4, 1.23444e50 as double, 5, 'gdgd\\dhdjh"dhdhd' as char, 6, "0:45:49.000001" AS time, 7, "2011-04-05 0:45:49.000001" AS datetime, 8, "2011-04-05" AS date));
|
||||
|
||||
--echo #
|
||||
--echo # CHECK test
|
||||
--echo #
|
||||
SELECT COLUMN_CHECK(COLUMN_CREATE(1,'a'));
|
||||
SELECT COLUMN_CHECK('abracadabra');
|
||||
SELECT COLUMN_CHECK('');
|
||||
SELECT COLUMN_CHECK(NULL);
|
||||
|
2644
mysys/ma_dyncol.c
2644
mysys/ma_dyncol.c
File diff suppressed because it is too large
Load Diff
102
mysys/string.c
102
mysys/string.c
@ -175,6 +175,34 @@ my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
my_bool dynstr_append_quoted(DYNAMIC_STRING *str,
|
||||
const char *append, size_t len)
|
||||
{
|
||||
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++]= '"';
|
||||
for (i= 0; i < len; i++)
|
||||
{
|
||||
register char c= append[i];
|
||||
if (c == '"' || c == '\\')
|
||||
{
|
||||
if (!lim)
|
||||
{
|
||||
if (dynstr_realloc(str, additional))
|
||||
return TRUE;
|
||||
lim= additional;
|
||||
}
|
||||
lim--;
|
||||
str->str[str->length++]= '\\';
|
||||
}
|
||||
str->str[str->length++]= c;
|
||||
}
|
||||
str->str[str->length++]= '"';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void dynstr_free(DYNAMIC_STRING *str)
|
||||
{
|
||||
@ -193,3 +221,77 @@ void dynstr_reassociate(DYNAMIC_STRING *str, char **ptr, size_t *length,
|
||||
*alloc_length= str->max_length;
|
||||
str->str=0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
copy a string from one character set to another
|
||||
|
||||
SYNOPSIS
|
||||
copy_and_convert()
|
||||
to Store result here
|
||||
to_cs Character set of result string
|
||||
from Copy from here
|
||||
from_length Length of from string
|
||||
from_cs From character set
|
||||
|
||||
NOTES
|
||||
'to' must be big enough as form_length * to_cs->mbmaxlen
|
||||
|
||||
RETURN
|
||||
length of bytes copied to 'to'
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
int cnvres;
|
||||
my_wc_t wc;
|
||||
const uchar *from_end= (const uchar*) from+from_length;
|
||||
char *to_start= to;
|
||||
uchar *to_end= (uchar*) to+to_length;
|
||||
my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
|
||||
my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb;
|
||||
uint error_count= 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from,
|
||||
from_end)) > 0)
|
||||
from+= cnvres;
|
||||
else if (cnvres == MY_CS_ILSEQ)
|
||||
{
|
||||
error_count++;
|
||||
from++;
|
||||
wc= '?';
|
||||
}
|
||||
else if (cnvres > MY_CS_TOOSMALL)
|
||||
{
|
||||
/*
|
||||
A correct multibyte sequence detected
|
||||
But it doesn't have Unicode mapping.
|
||||
*/
|
||||
error_count++;
|
||||
from+= (-cnvres);
|
||||
wc= '?';
|
||||
}
|
||||
else
|
||||
break; // Not enough characters
|
||||
|
||||
outp:
|
||||
if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0)
|
||||
to+= cnvres;
|
||||
else if (cnvres == MY_CS_ILUNI && wc != '?')
|
||||
{
|
||||
error_count++;
|
||||
wc= '?';
|
||||
goto outp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*errors= error_count;
|
||||
return (uint32) (to - to_start);
|
||||
}
|
||||
|
@ -523,7 +523,7 @@ public:
|
||||
|
||||
struct st_dyncall_create_def
|
||||
{
|
||||
Item *num, *value;
|
||||
Item *key, *value;
|
||||
CHARSET_INFO *cs;
|
||||
uint len, frac;
|
||||
DYNAMIC_COLUMN_TYPE type;
|
||||
|
@ -6048,24 +6048,87 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
longlong Item_func_dyncol_exists::val_int()
|
||||
longlong Item_func_dyncol_check::val_int()
|
||||
{
|
||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||
String tmp(buff, sizeof(buff), &my_charset_bin);
|
||||
DYNAMIC_COLUMN col;
|
||||
String *str;
|
||||
ulonglong num;
|
||||
enum enum_dyncol_func_result rc;
|
||||
|
||||
str= args[0]->val_str(&tmp);
|
||||
if (args[0]->null_value)
|
||||
goto null;
|
||||
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);
|
||||
if (rc < 0 && rc != ER_DYNCOL_FORMAT)
|
||||
{
|
||||
dynamic_column_error_message(rc);
|
||||
goto null;
|
||||
}
|
||||
null_value= FALSE;
|
||||
return rc == ER_DYNCOL_OK;
|
||||
|
||||
null:
|
||||
null_value= TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
longlong Item_func_dyncol_exists::val_int()
|
||||
{
|
||||
char buff[STRING_BUFFER_USUAL_SIZE], nmstrbuf[11];
|
||||
String tmp(buff, sizeof(buff), &my_charset_bin),
|
||||
nmbuf(nmstrbuf, sizeof(nmstrbuf), system_charset_info);
|
||||
DYNAMIC_COLUMN col;
|
||||
String *str;
|
||||
LEX_STRING buf, *name= NULL;
|
||||
ulonglong num= 0;
|
||||
enum enum_dyncol_func_result rc;
|
||||
|
||||
if (args[1]->result_type() == INT_RESULT)
|
||||
num= args[1]->val_int();
|
||||
else
|
||||
{
|
||||
String *nm= args[1]->val_str(&nmbuf);
|
||||
if (!nm || args[1]->null_value)
|
||||
{
|
||||
null_value= 1;
|
||||
return 1;
|
||||
}
|
||||
if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
|
||||
{
|
||||
buf.str= (char *) nm->ptr();
|
||||
buf.length= nm->length();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint strlen;
|
||||
uint dummy_errors;
|
||||
buf.str= (char *)sql_alloc((strlen= nm->length() *
|
||||
my_charset_utf8_general_ci.mbmaxlen + 1));
|
||||
if (buf.str)
|
||||
{
|
||||
buf.length=
|
||||
copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
|
||||
nm->ptr(), nm->length(), nm->charset(),
|
||||
&dummy_errors);
|
||||
}
|
||||
else
|
||||
buf.length= 0;
|
||||
}
|
||||
name= &buf;
|
||||
}
|
||||
str= args[0]->val_str(&tmp);
|
||||
if (args[0]->null_value || args[1]->null_value || num > UINT_MAX16)
|
||||
goto null;
|
||||
col.length= str->length();
|
||||
/* We do not change the string, so could do this trick */
|
||||
col.str= (char *)str->ptr();
|
||||
rc= dynamic_column_exists(&col, (uint) num);
|
||||
rc= ((name == NULL) ?
|
||||
dynamic_column_exists(&col, (uint) num) :
|
||||
dynamic_column_exists_str(&col, name));
|
||||
if (rc < 0)
|
||||
{
|
||||
dynamic_column_error_message(rc);
|
||||
|
@ -1861,6 +1861,14 @@ public:
|
||||
Item *neg_transformer(THD *thd);
|
||||
};
|
||||
|
||||
class Item_func_dyncol_check :public Item_bool_func
|
||||
{
|
||||
public:
|
||||
Item_func_dyncol_check(Item *str) :Item_bool_func(str) {}
|
||||
longlong val_int();
|
||||
const char *func_name() const { return "column_check"; }
|
||||
};
|
||||
|
||||
class Item_func_dyncol_exists :public Item_bool_func
|
||||
{
|
||||
public:
|
||||
|
@ -5704,7 +5704,7 @@ static List<Item> *create_func_dyncol_prepare(THD *thd,
|
||||
for (uint i= 0; (def= li++) ;)
|
||||
{
|
||||
dfs[0][i++]= *def;
|
||||
args->push_back(def->num);
|
||||
args->push_back(def->key);
|
||||
args->push_back(def->value);
|
||||
}
|
||||
return args;
|
||||
@ -5720,6 +5720,10 @@ 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)
|
||||
@ -5740,7 +5744,7 @@ Item *create_func_dyncol_add(THD *thd, Item *str,
|
||||
Item *create_func_dyncol_delete(THD *thd, Item *str, List<Item> &nums)
|
||||
{
|
||||
DYNCALL_CREATE_DEF *dfs;
|
||||
Item *num;
|
||||
Item *key;
|
||||
List_iterator_fast<Item> it(nums);
|
||||
List<Item> *args= new (thd->mem_root) List<Item>;
|
||||
|
||||
@ -5750,12 +5754,12 @@ Item *create_func_dyncol_delete(THD *thd, Item *str, List<Item> &nums)
|
||||
if (!args || !dfs)
|
||||
return NULL;
|
||||
|
||||
for (uint i= 0; (num= it++); i++)
|
||||
for (uint i= 0; (key= it++); i++)
|
||||
{
|
||||
dfs[i].num= num;
|
||||
dfs[i].key= key;
|
||||
dfs[i].value= new Item_null();
|
||||
dfs[i].type= DYN_COL_INT;
|
||||
args->push_back(dfs[i].num);
|
||||
args->push_back(dfs[i].key);
|
||||
args->push_back(dfs[i].value);
|
||||
}
|
||||
|
||||
|
@ -180,5 +180,6 @@ Item *create_func_dyncol_get(THD *thd, Item *num, Item *str,
|
||||
Cast_target cast_type,
|
||||
const char *c_len, const char *c_dec,
|
||||
CHARSET_INFO *cs);
|
||||
Item *create_func_dyncol_json(THD *thd, Item *str);
|
||||
#endif
|
||||
|
||||
|
@ -3760,7 +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), nums(0)
|
||||
: Item_str_func(args), defs(dfs), vals(0), keys(NULL), names(FALSE),
|
||||
force_names(FALSE)
|
||||
{
|
||||
DBUG_ASSERT((args.elements & 0x1) == 0); // even number of arguments
|
||||
}
|
||||
@ -3768,13 +3769,26 @@ Item_func_dyncol_create::Item_func_dyncol_create(List<Item> &args,
|
||||
|
||||
bool Item_func_dyncol_create::fix_fields(THD *thd, Item **ref)
|
||||
{
|
||||
uint i;
|
||||
bool res= Item_func::fix_fields(thd, ref); // no need Item_str_func here
|
||||
if (!res)
|
||||
{
|
||||
vals= (DYNAMIC_COLUMN_VALUE *) alloc_root(thd->mem_root,
|
||||
sizeof(DYNAMIC_COLUMN_VALUE) *
|
||||
(arg_count / 2));
|
||||
nums= (uint *) alloc_root(thd->mem_root,
|
||||
sizeof(uint) * (arg_count / 2));
|
||||
return res || vals == 0 || nums == 0;
|
||||
for (i= 0; i + 1 < arg_count && args[i]->result_type() == INT_RESULT; i+= 2);
|
||||
if (i + 1 < arg_count)
|
||||
{
|
||||
names= TRUE;
|
||||
}
|
||||
|
||||
keys= (uchar *) alloc_root(thd->mem_root,
|
||||
(sizeof(LEX_STRING) > sizeof(uint) ?
|
||||
sizeof(LEX_STRING) :
|
||||
sizeof(uint)) *
|
||||
(arg_count / 2));
|
||||
}
|
||||
return res || vals == 0 || keys == 0;
|
||||
}
|
||||
|
||||
|
||||
@ -3785,13 +3799,14 @@ void Item_func_dyncol_create::fix_length_and_dec()
|
||||
decimals= 0;
|
||||
}
|
||||
|
||||
void Item_func_dyncol_create::prepare_arguments()
|
||||
bool Item_func_dyncol_create::prepare_arguments(bool force_names_arg)
|
||||
{
|
||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||
String *res, tmp(buff, sizeof(buff), &my_charset_bin);
|
||||
uint column_count= (arg_count / 2);
|
||||
uint i;
|
||||
my_decimal dtmp, *dres;
|
||||
force_names= force_names_arg;
|
||||
|
||||
/* get values */
|
||||
for (i= 0; i < column_count; i++)
|
||||
@ -3850,7 +3865,54 @@ void Item_func_dyncol_create::prepare_arguments()
|
||||
break;
|
||||
}
|
||||
}
|
||||
nums[i]= (uint) args[i * 2]->val_int();
|
||||
if (names || force_names)
|
||||
{
|
||||
res= args[i * 2]->val_str(&tmp);
|
||||
if (res)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint strlen;
|
||||
uint dummy_errors;
|
||||
char *str=
|
||||
(char *)sql_alloc((strlen= res->length() *
|
||||
my_charset_utf8_general_ci.mbmaxlen + 1));
|
||||
if (str)
|
||||
{
|
||||
((LEX_STRING *)keys)[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;
|
||||
}
|
||||
else
|
||||
((LEX_STRING *)keys)[i].length= 0;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((LEX_STRING *)keys)[i].length= 0;
|
||||
((LEX_STRING *)keys)[i].str= NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
((uint *)keys)[i]= (uint) args[i * 2]->val_int();
|
||||
if (args[i * 2]->null_value)
|
||||
{
|
||||
/* to make cleanup possible */
|
||||
for (; i < column_count; i++)
|
||||
vals[i].type= DYN_COL_NULL;
|
||||
return 1;
|
||||
}
|
||||
vals[i].type= type;
|
||||
switch (type) {
|
||||
case DYN_COL_NULL:
|
||||
@ -3918,6 +3980,7 @@ void Item_func_dyncol_create::prepare_arguments()
|
||||
vals[i].type= DYN_COL_NULL;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void Item_func_dyncol_create::cleanup_arguments()
|
||||
@ -3930,6 +3993,7 @@ void Item_func_dyncol_create::cleanup_arguments()
|
||||
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)
|
||||
@ -3940,9 +4004,15 @@ String *Item_func_dyncol_create::val_str(String *str)
|
||||
enum enum_dyncol_func_result rc;
|
||||
DBUG_ASSERT((arg_count & 0x1) == 0); // even number of arguments
|
||||
|
||||
prepare_arguments();
|
||||
|
||||
if ((rc= dynamic_column_create_many(&col, column_count, nums, vals)))
|
||||
if (prepare_arguments(FALSE))
|
||||
{
|
||||
res= NULL;
|
||||
null_value= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((rc= dynamic_column_create_many_fmt(&col, column_count, keys,
|
||||
vals, names || force_names)))
|
||||
{
|
||||
dynamic_column_error_message(rc);
|
||||
dynamic_column_column_free(&col);
|
||||
@ -3960,6 +4030,7 @@ String *Item_func_dyncol_create::val_str(String *str)
|
||||
res= &str_value;
|
||||
null_value= FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
cleanup_arguments();
|
||||
@ -4026,6 +4097,40 @@ void Item_func_dyncol_create::print(String *str,
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
String *Item_func_dyncol_json::val_str(String *str)
|
||||
{
|
||||
DYNAMIC_STRING json, col;
|
||||
String *res;
|
||||
enum enum_dyncol_func_result rc;
|
||||
|
||||
res= args[0]->val_str(str);
|
||||
if (args[0]->null_value)
|
||||
goto null;
|
||||
|
||||
col.str= (char *)res->ptr();
|
||||
col.length= res->length();
|
||||
if ((rc= dynamic_column_json(&col, &json)))
|
||||
{
|
||||
dynamic_column_error_message(rc);
|
||||
goto null;
|
||||
}
|
||||
bzero(&col, sizeof(col));
|
||||
{
|
||||
/* Move result from DYNAMIC_COLUMN to str */
|
||||
char *ptr;
|
||||
size_t length, alloc_length;
|
||||
dynstr_reassociate(&json, &ptr, &length, &alloc_length);
|
||||
str->reassociate(ptr, (uint32) length, (uint32) alloc_length,
|
||||
&my_charset_utf8_general_ci);
|
||||
null_value= FALSE;
|
||||
}
|
||||
return str;
|
||||
|
||||
null:
|
||||
bzero(&col, sizeof(col));
|
||||
null_value= TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
String *Item_func_dyncol_add::val_str(String *str)
|
||||
{
|
||||
@ -4037,17 +4142,19 @@ String *Item_func_dyncol_add::val_str(String *str)
|
||||
|
||||
/* We store the packed data last */
|
||||
res= args[arg_count - 1]->val_str(str);
|
||||
if (args[arg_count - 1]->null_value)
|
||||
goto null;
|
||||
if (args[arg_count - 1]->null_value ||
|
||||
init_dynamic_string(&col, NULL, res->length() + STRING_BUFFER_USUAL_SIZE,
|
||||
STRING_BUFFER_USUAL_SIZE);
|
||||
STRING_BUFFER_USUAL_SIZE))
|
||||
goto null;
|
||||
|
||||
col.length= res->length();
|
||||
memcpy(col.str, res->ptr(), col.length);
|
||||
|
||||
prepare_arguments();
|
||||
if (prepare_arguments(dynamic_column_has_names(&col)))
|
||||
goto null;
|
||||
|
||||
if ((rc= dynamic_column_update_many(&col, column_count, nums, vals)))
|
||||
if ((rc= dynamic_column_update_many_fmt(&col, column_count, keys,
|
||||
vals, names || force_names)))
|
||||
{
|
||||
dynamic_column_error_message(rc);
|
||||
dynamic_column_column_free(&col);
|
||||
@ -4066,7 +4173,6 @@ String *Item_func_dyncol_add::val_str(String *str)
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
dynamic_column_column_free(&col);
|
||||
cleanup_arguments();
|
||||
|
||||
return str;
|
||||
@ -4100,10 +4206,48 @@ bool Item_dyncol_get::get_dyn_value(DYNAMIC_COLUMN_VALUE *val, String *tmp)
|
||||
{
|
||||
DYNAMIC_COLUMN dyn_str;
|
||||
String *res;
|
||||
longlong num;
|
||||
longlong num= 0;
|
||||
LEX_STRING buf, *name= NULL;
|
||||
char nmstrbuf[11];
|
||||
String nmbuf(nmstrbuf, sizeof(nmstrbuf), system_charset_info);
|
||||
enum enum_dyncol_func_result rc;
|
||||
|
||||
if (args[1]->result_type() == INT_RESULT)
|
||||
num= args[1]->val_int();
|
||||
else
|
||||
{
|
||||
String *nm= args[1]->val_str(&nmbuf);
|
||||
if (!nm || args[1]->null_value)
|
||||
{
|
||||
null_value= 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
|
||||
{
|
||||
buf.str= (char *) nm->ptr();
|
||||
buf.length= nm->length();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint strlen;
|
||||
uint dummy_errors;
|
||||
buf.str= (char *)sql_alloc((strlen= nm->length() *
|
||||
my_charset_utf8_general_ci.mbmaxlen + 1));
|
||||
if (buf.str)
|
||||
{
|
||||
buf.length=
|
||||
copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
|
||||
nm->ptr(), nm->length(), nm->charset(),
|
||||
&dummy_errors);
|
||||
}
|
||||
else
|
||||
buf.length= 0;
|
||||
}
|
||||
name= &buf;
|
||||
}
|
||||
|
||||
|
||||
if (args[1]->null_value || num < 0 || num > INT_MAX)
|
||||
{
|
||||
null_value= 1;
|
||||
@ -4119,7 +4263,9 @@ 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= dynamic_column_get(&dyn_str, (uint) num, val)))
|
||||
if ((rc= ((name == NULL) ?
|
||||
dynamic_column_get(&dyn_str, (uint) num, val) :
|
||||
dynamic_column_get_str(&dyn_str, name, val))))
|
||||
{
|
||||
dynamic_column_error_message(rc);
|
||||
null_value= 1;
|
||||
@ -4468,6 +4614,8 @@ null:
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
append_identifier(THD *thd, String *packet, const char *name, uint length);
|
||||
|
||||
void Item_dyncol_get::print(String *str, enum_query_type query_type)
|
||||
{
|
||||
@ -4492,26 +4640,30 @@ 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(&col, &arr)))
|
||||
if ((rc= dynamic_column_list_str(&col, &arr)))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
We support elements from 0 - 65536, so max size for one element is
|
||||
6 (including ,).
|
||||
We estimate average name length as 10
|
||||
*/
|
||||
if (str->alloc(arr.elements * 6))
|
||||
if (str->alloc(arr.elements * 13))
|
||||
goto null;
|
||||
|
||||
str->length(0);
|
||||
str->set_charset(&my_charset_utf8_general_ci);
|
||||
for (i= 0; i < arr.elements; i++)
|
||||
{
|
||||
str->qs_append(*dynamic_element(&arr, i, uint*));
|
||||
LEX_STRING *name= dynamic_element(&arr, i, LEX_STRING *);
|
||||
append_identifier(current_thd, str, name->str, name->length);
|
||||
if (i < arr.elements - 1)
|
||||
str->qs_append(',');
|
||||
my_free(name->str);
|
||||
}
|
||||
|
||||
null_value= FALSE;
|
||||
|
@ -1001,8 +1001,9 @@ class Item_func_dyncol_create: public Item_str_func
|
||||
protected:
|
||||
DYNCALL_CREATE_DEF *defs;
|
||||
DYNAMIC_COLUMN_VALUE *vals;
|
||||
uint *nums;
|
||||
void prepare_arguments();
|
||||
uchar *keys;
|
||||
bool names, force_names;
|
||||
bool prepare_arguments(bool force_names);
|
||||
void cleanup_arguments();
|
||||
void print_arguments(String *str, enum_query_type query_type);
|
||||
public:
|
||||
@ -1026,6 +1027,19 @@ public:
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
};
|
||||
|
||||
class Item_func_dyncol_json: public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_func_dyncol_json(Item *str) :Item_str_func(str) {}
|
||||
const char *func_name() const{ return "column_json"; }
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec()
|
||||
{
|
||||
maybe_null= TRUE;
|
||||
collation.set(&my_charset_bin);
|
||||
decimals= 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
The following functions is always called from an Item_cast function
|
||||
|
@ -123,10 +123,12 @@ static SYMBOL symbols[] = {
|
||||
{ "COLUMN_NAME", SYM(COLUMN_NAME_SYM)},
|
||||
{ "COLUMNS", SYM(COLUMNS)},
|
||||
{ "COLUMN_ADD", SYM(COLUMN_ADD_SYM)},
|
||||
{ "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)},
|
||||
|
@ -750,79 +750,6 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
|
||||
Help functions
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
copy a string from one character set to another
|
||||
|
||||
SYNOPSIS
|
||||
copy_and_convert()
|
||||
to Store result here
|
||||
to_cs Character set of result string
|
||||
from Copy from here
|
||||
from_length Length of from string
|
||||
from_cs From character set
|
||||
|
||||
NOTES
|
||||
'to' must be big enough as form_length * to_cs->mbmaxlen
|
||||
|
||||
RETURN
|
||||
length of bytes copied to 'to'
|
||||
*/
|
||||
|
||||
|
||||
static 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)
|
||||
{
|
||||
int cnvres;
|
||||
my_wc_t wc;
|
||||
const uchar *from_end= (const uchar*) from+from_length;
|
||||
char *to_start= to;
|
||||
uchar *to_end= (uchar*) to+to_length;
|
||||
my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
|
||||
my_charset_conv_wc_mb wc_mb= to_cs->cset->wc_mb;
|
||||
uint error_count= 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from,
|
||||
from_end)) > 0)
|
||||
from+= cnvres;
|
||||
else if (cnvres == MY_CS_ILSEQ)
|
||||
{
|
||||
error_count++;
|
||||
from++;
|
||||
wc= '?';
|
||||
}
|
||||
else if (cnvres > MY_CS_TOOSMALL)
|
||||
{
|
||||
/*
|
||||
A correct multibyte sequence detected
|
||||
But it doesn't have Unicode mapping.
|
||||
*/
|
||||
error_count++;
|
||||
from+= (-cnvres);
|
||||
wc= '?';
|
||||
}
|
||||
else
|
||||
break; // Not enough characters
|
||||
|
||||
outp:
|
||||
if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0)
|
||||
to+= cnvres;
|
||||
else if (cnvres == MY_CS_ILUNI && wc != '?')
|
||||
{
|
||||
error_count++;
|
||||
wc= '?';
|
||||
goto outp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*errors= error_count;
|
||||
return (uint32) (to - to_start);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -882,10 +882,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
%token COLLATION_SYM /* SQL-2003-N */
|
||||
%token COLUMNS
|
||||
%token COLUMN_ADD_SYM
|
||||
%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 */
|
||||
@ -8245,7 +8247,7 @@ dyncall_create_element:
|
||||
alloc_root(YYTHD->mem_root, sizeof(DYNCALL_CREATE_DEF));
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
$$->num= $1;
|
||||
$$->key= $1;
|
||||
$$->value= $3;
|
||||
$$->type= (DYNAMIC_COLUMN_TYPE)$4;
|
||||
$$->cs= lex->charset;
|
||||
@ -8798,6 +8800,13 @@ function_call_nonkeyword:
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
|
|
||||
COLUMN_CHECK_SYM '(' expr ')'
|
||||
{
|
||||
$$= new (YYTHD->mem_root) Item_func_dyncol_check($3);
|
||||
if ($$ == NULL)
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
|
|
||||
COLUMN_EXISTS_SYM '(' expr ',' expr ')'
|
||||
{
|
||||
@ -8819,6 +8828,13 @@ 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 ')'
|
||||
{
|
||||
@ -12908,10 +12924,12 @@ keyword:
|
||||
| CHECKPOINT_SYM {}
|
||||
| CLOSE_SYM {}
|
||||
| COLUMN_ADD_SYM {}
|
||||
| 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 {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user