Commit b11aa0df authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.5 into 10.6

parents 39001478 617dee34
...@@ -1366,5 +1366,21 @@ JSON_OBJECTAGG(a, e) ...@@ -1366,5 +1366,21 @@ JSON_OBJECTAGG(a, e)
DROP VIEW v; DROP VIEW v;
DROP TABLE t1; DROP TABLE t1;
# #
# MDEV-23004 When using GROUP BY with JSON_ARRAYAGG with joint table, the square brackets are not included.
#
CREATE TABLE t1(id int primary key, name varchar(50));
CREATE TABLE t2(id int, owner_id int);
INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3");
INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3);
SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id)) as materials
from t1 LEFT JOIN t2 on t1.id = t2.owner_id
GROUP BY t1.id ORDER BY id;
id materials
1 ["{\"id\": 1}","{\"id\": 2}"]
2 ["{\"id\": 3}"]
3 ["{\"id\": 4}"]
DROP TABLE t1;
DROP TABLE t2;
#
# End of 10.5 tests # End of 10.5 tests
# #
...@@ -856,6 +856,23 @@ SELECT * FROM v; ...@@ -856,6 +856,23 @@ SELECT * FROM v;
DROP VIEW v; DROP VIEW v;
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-23004 When using GROUP BY with JSON_ARRAYAGG with joint table, the square brackets are not included.
--echo #
CREATE TABLE t1(id int primary key, name varchar(50));
CREATE TABLE t2(id int, owner_id int);
INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3");
INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3);
SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id)) as materials
from t1 LEFT JOIN t2 on t1.id = t2.owner_id
GROUP BY t1.id ORDER BY id;
DROP TABLE t1;
DROP TABLE t2;
--echo # --echo #
--echo # End of 10.5 tests --echo # End of 10.5 tests
--echo # --echo #
......
/* Copyright (c) 2016, MariaDB Corporation /* Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -24,6 +24,10 @@ my_bool has_shannon_atomic_write= 0, has_fusion_io_atomic_write= 0, ...@@ -24,6 +24,10 @@ my_bool has_shannon_atomic_write= 0, has_fusion_io_atomic_write= 0,
#include <sys/ioctl.h> #include <sys/ioctl.h>
/* Linux seems to allow up to 15 partitions per block device.
Partition number 0 is the whole block device. */
# define SAME_DEV(fs_dev, blk_dev) \
(fs_dev == blk_dev) || ((fs_dev & ~15U) == blk_dev)
/*********************************************************************** /***********************************************************************
FUSION_IO FUSION_IO
...@@ -115,9 +119,9 @@ static my_bool test_if_shannon_card_exists() ...@@ -115,9 +119,9 @@ static my_bool test_if_shannon_card_exists()
sprintf(path, "/dev/df%c", dev_part); sprintf(path, "/dev/df%c", dev_part);
#ifdef TEST_SHANNON #ifdef TEST_SHANNON
if (lstat(path, &stat_buff) < 0) if (stat(path, &stat_buff) < 0)
{ {
printf("%s(): lstat failed.\n", __func__); printf("%s(): stat %s failed.\n", __func__, path);
break; break;
} }
#endif #endif
...@@ -147,7 +151,7 @@ static my_bool test_if_shannon_card_exists() ...@@ -147,7 +151,7 @@ static my_bool test_if_shannon_card_exists()
for (dev_no= 1 ; dev_no < 9 ; dev_no++) for (dev_no= 1 ; dev_no < 9 ; dev_no++)
{ {
sprintf(path, "/dev/df%c%d", dev_part, dev_no); sprintf(path, "/dev/df%c%d", dev_part, dev_no);
if (lstat(path, &stat_buff) < 0) if (stat(path, &stat_buff) < 0)
break; break;
shannon_devices[shannon_found_devices].st_dev= stat_buff.st_rdev; shannon_devices[shannon_found_devices].st_dev= stat_buff.st_rdev;
...@@ -194,7 +198,8 @@ static my_bool shannon_dev_has_atomic_write(struct shannon_dev *dev, ...@@ -194,7 +198,8 @@ static my_bool shannon_dev_has_atomic_write(struct shannon_dev *dev,
int fd= open(dev->dev_name, 0); int fd= open(dev->dev_name, 0);
if (fd < 0) if (fd < 0)
{ {
perror("open() failed!"); fprintf(stderr, "Unable to determine if atomic writes are supported:"
" open(\"%s\"): %m\n", dev->dev_name);
dev->atomic_size= 0; /* Don't try again */ dev->atomic_size= 0; /* Don't try again */
return FALSE; return FALSE;
} }
...@@ -248,7 +253,7 @@ static my_bool shannon_has_atomic_write(File file, int page_size) ...@@ -248,7 +253,7 @@ static my_bool shannon_has_atomic_write(File file, int page_size)
#ifdef TEST_SHANNON #ifdef TEST_SHANNON
printf("%s(): st_rdev=0x%lx\n", __func__, (ulong) dev->st_dev); printf("%s(): st_rdev=0x%lx\n", __func__, (ulong) dev->st_dev);
#endif #endif
if (stat_buff.st_dev == dev->st_dev) if (SAME_DEV(stat_buff.st_dev, dev->st_dev))
return shannon_dev_has_atomic_write(dev, page_size); return shannon_dev_has_atomic_write(dev, page_size);
} }
return 0; return 0;
...@@ -290,8 +295,7 @@ static my_bool test_if_sfx_card_exists() ...@@ -290,8 +295,7 @@ static my_bool test_if_sfx_card_exists()
sprintf(sfx_devices[sfx_found_devices].dev_name, "/dev/sfdv%dn1", sprintf(sfx_devices[sfx_found_devices].dev_name, "/dev/sfdv%dn1",
dev_num); dev_num);
if (lstat(sfx_devices[sfx_found_devices].dev_name, if (stat(sfx_devices[sfx_found_devices].dev_name, &stat_buff) < 0)
&stat_buff) < 0)
break; break;
sfx_devices[sfx_found_devices].st_dev= stat_buff.st_rdev; sfx_devices[sfx_found_devices].st_dev= stat_buff.st_rdev;
...@@ -316,14 +320,16 @@ static my_bool sfx_dev_has_atomic_write(struct sfx_dev *dev, ...@@ -316,14 +320,16 @@ static my_bool sfx_dev_has_atomic_write(struct sfx_dev *dev,
int fd= open(dev->dev_name, 0); int fd= open(dev->dev_name, 0);
if (fd < 0) if (fd < 0)
{ {
perror("open() failed!"); fprintf(stderr, "Unable to determine if atomic writes are supported:"
" open(\"%s\"): %m\n", dev->dev_name);
dev->atomic_size= 0; /* Don't try again */ dev->atomic_size= 0; /* Don't try again */
return FALSE;
} }
else
{
dev->atomic_size= ioctl(fd, SFX_GET_ATOMIC_SIZE); dev->atomic_size= ioctl(fd, SFX_GET_ATOMIC_SIZE);
close(fd); close(fd);
} }
}
return (page_size <= dev->atomic_size); return (page_size <= dev->atomic_size);
} }
...@@ -346,16 +352,10 @@ static my_bool sfx_has_atomic_write(File file, int page_size) ...@@ -346,16 +352,10 @@ static my_bool sfx_has_atomic_write(File file, int page_size)
struct sfx_dev *dev; struct sfx_dev *dev;
struct stat stat_buff; struct stat stat_buff;
if (fstat(file, &stat_buff) < 0) if (fstat(file, &stat_buff) == 0)
{ for (dev= sfx_devices; dev->st_dev; dev++)
return 0; if (SAME_DEV(stat_buff.st_dev, dev->st_dev))
}
for (dev = sfx_devices; dev->st_dev; dev++)
{
if (stat_buff.st_dev == dev->st_dev)
return sfx_dev_has_atomic_write(dev, page_size); return sfx_dev_has_atomic_write(dev, page_size);
}
return 0; return 0;
} }
/*********************************************************************** /***********************************************************************
...@@ -369,10 +369,13 @@ static my_bool sfx_has_atomic_write(File file, int page_size) ...@@ -369,10 +369,13 @@ static my_bool sfx_has_atomic_write(File file, int page_size)
void my_init_atomic_write(void) void my_init_atomic_write(void)
{ {
if ((has_shannon_atomic_write= test_if_shannon_card_exists()) || has_shannon_atomic_write= test_if_shannon_card_exists();
(has_fusion_io_atomic_write= test_if_fusion_io_card_exists()) || has_fusion_io_atomic_write= test_if_fusion_io_card_exists();
(has_sfx_atomic_write= test_if_sfx_card_exists())) has_sfx_atomic_write= test_if_sfx_card_exists();
my_may_have_atomic_write= 1;
my_may_have_atomic_write= has_shannon_atomic_write ||
has_fusion_io_atomic_write || has_sfx_atomic_write;
#ifdef TEST_SHANNON #ifdef TEST_SHANNON
printf("%s(): has_shannon_atomic_write=%d, my_may_have_atomic_write=%d\n", printf("%s(): has_shannon_atomic_write=%d, my_may_have_atomic_write=%d\n",
__func__, __func__,
......
...@@ -3754,6 +3754,12 @@ void Item_func_json_arrayagg::cut_max_length(String *result, ...@@ -3754,6 +3754,12 @@ void Item_func_json_arrayagg::cut_max_length(String *result,
} }
Item *Item_func_json_arrayagg::copy_or_same(THD* thd)
{
return new (thd->mem_root) Item_func_json_arrayagg(thd, this);
}
String* Item_func_json_arrayagg::val_str(String *str) String* Item_func_json_arrayagg::val_str(String *str)
{ {
if ((str= Item_func_group_concat::val_str(str))) if ((str= Item_func_group_concat::val_str(str)))
......
#ifndef ITEM_JSONFUNC_INCLUDED #ifndef ITEM_JSONFUNC_INCLUDED
#define ITEM_JSONFUNC_INCLUDED #define ITEM_JSONFUNC_INCLUDED
/* Copyright (c) 2016, MariaDB /* Copyright (c) 2016, 2021, MariaDB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -139,8 +139,8 @@ class Item_json_func: public Item_str_func ...@@ -139,8 +139,8 @@ class Item_json_func: public Item_str_func
:Item_str_func(thd, a, b) { } :Item_str_func(thd, a, b) { }
Item_json_func(THD *thd, List<Item> &list) Item_json_func(THD *thd, List<Item> &list)
:Item_str_func(thd, list) { } :Item_str_func(thd, list) { }
bool is_json_type() { return true; } bool is_json_type() override { return true; }
void make_send_field(THD *thd, Send_field *tmp_field) void make_send_field(THD *thd, Send_field *tmp_field) override
{ {
Item_str_func::make_send_field(thd, tmp_field); Item_str_func::make_send_field(thd, tmp_field);
static const Lex_cstring fmt(STRING_WITH_LEN("json")); static const Lex_cstring fmt(STRING_WITH_LEN("json"));
...@@ -655,7 +655,8 @@ class Item_func_json_arrayagg : public Item_func_group_concat ...@@ -655,7 +655,8 @@ class Item_func_json_arrayagg : public Item_func_group_concat
is_separator, limit_clause, row_limit, offset_limit) is_separator, limit_clause, row_limit, offset_limit)
{ {
} }
Item_func_json_arrayagg(THD *thd, Item_func_json_arrayagg *item); Item_func_json_arrayagg(THD *thd, Item_func_json_arrayagg *item) :
Item_func_group_concat(thd, item) {}
bool is_json_type() override { return true; } bool is_json_type() override { return true; }
LEX_CSTRING func_name_cstring() const override LEX_CSTRING func_name_cstring() const override
...@@ -663,10 +664,11 @@ class Item_func_json_arrayagg : public Item_func_group_concat ...@@ -663,10 +664,11 @@ class Item_func_json_arrayagg : public Item_func_group_concat
static LEX_CSTRING name= {STRING_WITH_LEN("json_arrayagg(") }; static LEX_CSTRING name= {STRING_WITH_LEN("json_arrayagg(") };
return name; return name;
} }
enum Sumfunctype sum_func() const override {return JSON_ARRAYAGG_FUNC;} enum Sumfunctype sum_func() const override { return JSON_ARRAYAGG_FUNC; }
String* val_str(String *str) override; String* val_str(String *str) override;
Item *copy_or_same(THD* thd) override;
Item *get_copy(THD *thd) override Item *get_copy(THD *thd) override
{ return get_item_copy<Item_func_json_arrayagg>(thd, this); } { return get_item_copy<Item_func_json_arrayagg>(thd, this); }
}; };
...@@ -705,10 +707,8 @@ class Item_func_json_objectagg : public Item_sum ...@@ -705,10 +707,8 @@ class Item_func_json_objectagg : public Item_sum
void update_field() override { DBUG_ASSERT(0); } // not used void update_field() override { DBUG_ASSERT(0); } // not used
bool fix_fields(THD *,Item **) override; bool fix_fields(THD *,Item **) override;
double val_real() override double val_real() override { return 0.0; }
{ return 0.0; } longlong val_int() override { return 0; }
longlong val_int() override
{ return 0; }
my_decimal *val_decimal(my_decimal *decimal_value) override my_decimal *val_decimal(my_decimal *decimal_value) override
{ {
my_decimal_set_zero(decimal_value); my_decimal_set_zero(decimal_value);
...@@ -718,7 +718,7 @@ class Item_func_json_objectagg : public Item_sum ...@@ -718,7 +718,7 @@ class Item_func_json_objectagg : public Item_sum
{ {
return get_date_from_string(thd, ltime, fuzzydate); return get_date_from_string(thd, ltime, fuzzydate);
} }
String *val_str(String* str) override; String* val_str(String* str) override;
Item *copy_or_same(THD* thd) override; Item *copy_or_same(THD* thd) override;
void no_rows_in_result() override {} void no_rows_in_result() override {}
Item *get_copy(THD *thd) override Item *get_copy(THD *thd) override
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment