Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

执行json_object,结果返回字段顺序会改变,和mariadb,mysql数据库不一样 #68

Closed
co63oc opened this issue Jul 6, 2022 · 3 comments

Comments

@co63oc
Copy link
Contributor

co63oc commented Jul 6, 2022

mysql> SELECT JSON_OBJECT('id', 123, 'name', 'polardb-x');
+---------------------------------------------+
| JSON_OBJECT('id', 123, 'name', 'polardb-x') |
+---------------------------------------------+
| {"name":"polardb-x","id":123} |
+---------------------------------------------+
1 row in set (0.00 sec)

mariadb数据库的结果为,这应该是和mysql数据库一样
MariaDB [(none)]> SELECT JSON_OBJECT('id', 123, 'name', 'polardb-x');
+---------------------------------------------+
| JSON_OBJECT('id', 123, 'name', 'polardb-x') |
+---------------------------------------------+
| {"id": 123, "name": "polardb-x"} |
+---------------------------------------------+
1 row in set (0.000 sec)

@co63oc
Copy link
Contributor Author

co63oc commented Jul 6, 2022

mysqld测试结果
mysql> SELECT JSON_OBJECT('id', 123, 'name', 'polardb-x');
+---------------------------------------------+
| JSON_OBJECT('id', 123, 'name', 'polardb-x') |
+---------------------------------------------+
| {"id": 123, "name": "polardb-x"} |
+---------------------------------------------+
1 row in set (0.00 sec)

@co63oc co63oc changed the title 执行json_object,结果返回字段顺序会改变,和mariadb数据库不一样 执行json_object,结果返回字段顺序会改变,和mariadb,mysql数据库不一样 Jul 6, 2022
@co63oc
Copy link
Contributor Author

co63oc commented Jul 6, 2022

polardbx-optimizer\src\main\java\com\alibaba\polardbx\optimizer\core\function\calc\scalar\json\JsonObject.java
对应源码,生fastjson成json时会有顺序,没找到怎么改变设置顺序

    @Override
    public Object compute(Object[] args, ExecutionContext ec) {
        if (args.length % 2 != 0) {
            throw JsonParserException.wrongParamCount(getFunctionNames()[0]);
        }

        Map<String, Object> resultJson = Maps.newHashMap();
        for (int i = 0; i < args.length; i += 2) {
            if (args[i] == null) {
                throw new JsonParserException("JSON documents may not contain NULL member names.");
            }

            if (i + 1 < args.length) {
                resultJson.put(DataTypeUtil.convert(operandTypes.get(i), DataTypes.StringType, args[i]), args[i + 1]);
            } else {
                throw JsonParserException.wrongParamCount(getFunctionNames()[0]);
            }
        }

        return JSON.toJSONString(resultJson);
    }

@F-ca7
Copy link
Collaborator

F-ca7 commented Jul 29, 2022

关于MySQL 对 json_object输出顺序的描述:https://dev.mysql.com/doc/refman/8.0/en/json.html#json-normalization

To make lookups more efficient, MySQL also sorts the keys of a JSON object. You should be aware that the result of this ordering is subject to change and not guaranteed to be consistent across releases.

MySQL会对 JSON对象的key进行排序,但是不保证这个顺序在每个发行版都是一致的。

而PolarDB-X中调用了FastJson的接口,底层com.alibaba.fastjson.serializer.MapSerializer 是基于HashMap的遍历,这个同样也是不保证顺序的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants