JSON_OBJECT 内部 JSON_ARRAYAGG 有时 return json 数组,有时是字符串
JSON_OBJECT inside JSON_ARRAYAGG sometimes return json array, sometimes string
在 MariaDB 10.5.12 中,JSON_OBJECT
的功能很奇怪 returns 不同的数据类型,具体取决于联接中是否存在键索引-table。
我一直在尝试在 json 数组中获取 post 评论。并注意到聚合函数的输出发生了奇怪的变化。
虽然它始终提供 相同的正确结果,但包装各不相同。有时是 escaped string
需要额外的 json 解析,有时是现成的 json array
.
渐渐地我能够接近原因。这是显示错误的最低限度工作查询。
SELECT
JSON_ARRAYAGG(DISTINCT JSON_OBJECT(
'comment_id', comment.id,
'text', comment.text
) ORDER BY comment.id) AS comments
FROM post
LEFT JOIN comment ON comment.post_id = post.id
LEFT JOIN vote ON vote.user_id = 1 AND vote.post_id = post.id
GROUP BY post.id
前提是user_id
键索引存在于vote
table.
如果按user_id
字段条件出现,输出为转义字符串:
LEFT JOIN vote ON vote.user_id = 123 AND vote.post_id = post.id
["{\"tag_id\": 1, \"name\": \"conubia\"}","{\"tag_id\": 21, \"name\": \"convallis\"}"]
["{\"tag_id\": 40, \"name\": \"amet\"}","{\"tag_id\": 41, \"name\": \"neque\"}"]
如果合并没有由user_id
字段条件发生,输出为json数组:
LEFT JOIN vote ON vote.user_id = -1 AND vote.post_id = post.id
[{"tag_id": 1, "name": "conubia"},{"tag_id": 21, "name": "convallis"}]
[{"tag_id": 40, "name": "amet"},{"tag_id": 41, "name": "neque"}]
如果没有key索引user_id
,在所有join条件下,输出转义字符串:
["{\"tag_id\": 1, \"name\": \"conubia\"}","{\"tag_id\": 21, \"name\": \"convallis\"}"]
["{\"tag_id\": 40, \"name\": \"amet\"}","{\"tag_id\": 41, \"name\": \"neque\"}"]
投票给 DDL
CREATE TABLE `vote` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NULL DEFAULT NULL,
`post_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `user_id` (`user_id`) USING BTREE
)
ENGINE=InnoDB
AUTO_INCREMENT=1
问题
是否可以在不删除索引的情况下,通过数据库防止意外更改函数输出?
假设
我想我可以使用 CAST,但它对我不起作用。
看起来这与 JSON 转义中的错误有关。
- https://jira.mariadb.org/browse/MDEV-26506
- https://jira.mariadb.org/browse/MDEV-21902
- https://jira.mariadb.org/browse/MDEV-22837
该问题已在新版本中修复。在 MariaDB 10.6.5 中测试。
在 MariaDB 10.5.12 中,JSON_OBJECT
的功能很奇怪 returns 不同的数据类型,具体取决于联接中是否存在键索引-table。
我一直在尝试在 json 数组中获取 post 评论。并注意到聚合函数的输出发生了奇怪的变化。
虽然它始终提供 相同的正确结果,但包装各不相同。有时是 escaped string
需要额外的 json 解析,有时是现成的 json array
.
渐渐地我能够接近原因。这是显示错误的最低限度工作查询。
SELECT
JSON_ARRAYAGG(DISTINCT JSON_OBJECT(
'comment_id', comment.id,
'text', comment.text
) ORDER BY comment.id) AS comments
FROM post
LEFT JOIN comment ON comment.post_id = post.id
LEFT JOIN vote ON vote.user_id = 1 AND vote.post_id = post.id
GROUP BY post.id
前提是user_id
键索引存在于vote
table.
如果按user_id
字段条件出现,输出为转义字符串:
LEFT JOIN vote ON vote.user_id = 123 AND vote.post_id = post.id
["{\"tag_id\": 1, \"name\": \"conubia\"}","{\"tag_id\": 21, \"name\": \"convallis\"}"]
["{\"tag_id\": 40, \"name\": \"amet\"}","{\"tag_id\": 41, \"name\": \"neque\"}"]
如果合并没有由user_id
字段条件发生,输出为json数组:
LEFT JOIN vote ON vote.user_id = -1 AND vote.post_id = post.id
[{"tag_id": 1, "name": "conubia"},{"tag_id": 21, "name": "convallis"}]
[{"tag_id": 40, "name": "amet"},{"tag_id": 41, "name": "neque"}]
如果没有key索引user_id
,在所有join条件下,输出转义字符串:
["{\"tag_id\": 1, \"name\": \"conubia\"}","{\"tag_id\": 21, \"name\": \"convallis\"}"]
["{\"tag_id\": 40, \"name\": \"amet\"}","{\"tag_id\": 41, \"name\": \"neque\"}"]
投票给 DDL
CREATE TABLE `vote` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NULL DEFAULT NULL,
`post_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `user_id` (`user_id`) USING BTREE
)
ENGINE=InnoDB
AUTO_INCREMENT=1
问题
是否可以在不删除索引的情况下,通过数据库防止意外更改函数输出?
假设
我想我可以使用 CAST,但它对我不起作用。
看起来这与 JSON 转义中的错误有关。
- https://jira.mariadb.org/browse/MDEV-26506
- https://jira.mariadb.org/browse/MDEV-21902
- https://jira.mariadb.org/browse/MDEV-22837
该问题已在新版本中修复。在 MariaDB 10.6.5 中测试。