Thread

  1. BUG #19110: the order of elements in a json object in database is different then the order of elements

    PG Bug reporting form <noreply@postgresql.org> — 2025-11-11T14:26:34Z

    The following bug has been logged on the website:
    
    Bug reference:      19110
    Logged by:          Tal Tabakman
    Email address:      tal.tabakman@foretellix.com
    PostgreSQL version: 14.0
    Operating system:   ubuntu 22.04
    Description:        
    
    Hi,
    i am using a Kotlin based application which used spring-boot3.5.6 +
    hibernate6 on top of postgresql14
    i have LinkedHashMap construct defined as follows
    
        @JdbcTypeCode(SqlTypes.JSON)
        @Column(name = "compound_rules", columnDefinition = "json")
        var compoundRules: LinkedHashMap<String, CompoundRuleData>,
    
    This hash map is stored as a json object under a column defined as a json
    column (and not jsonb)
    what we are noticing is that when we send the relevant object from our
    application to postgres and fetch it back (using update and select queries
    respectivally) , the order of elemenet in the hash map is changing which
    causes a problem in our end.
    sevaral facts
    1. what we see is that the linked hash map is serialized to a json string in
    a way that preserve the order of elements , this is a key feature of linked
    hash maps which we relay on
    2. we also see that the correct json string is properly sent via socket to
    postgres.
    3. However, the log in postgres side shows a changed order of elements
    
    This is a log file from the application side, prior to sending the data to
    posgres (note the order of "test_rule_0" and "test_rule_1")
    
    2025-11-09 12:21:47,140 [TRACE] [http-nio-8080-exec-4] [opId=ae543957aff2]
    [userEmail=admin@fmanager.com] [ResourceRegistryStandardImpl.java:96]
    Releasing statement [/* update for
    com.foretellix.manager.services.workspace.WorkspaceCompoundRulesData
    */update workspace_compound_rules set
    compound_rules=(‘{“4d3f85b4962c50fd7f38”:{“id”:“4d3f85b4962c50fd7f38”,“name”:“test_rule_0”,“modifiedAt”:1762683706,“lastModifiedById”:“42e6b2f773365a5fae82”,“createdById”:“42e6b2f773365a5fae82”,“rulesParams”:{“temporalRelationParams”:{“intervalFilters”:[{“elements”:[{“_type”:“intervals”,“include”:true,“scenarioName”:null,“protected”:false,“logicalOperator”:“AND”,“intervalName”:“sut.lead_vehicle”,“intervalType”:“MatchIntervalData”,“childrenFilter”:null,“intervalCriteria”:}],“logicalOperator”:“AND”,“isEmpty”:false},{“elements”:[{“_type”:“intervals”,“include”:true,“scenarioName”:null,“protected”:false,“logicalOperator”:“AND”,“intervalName”:“sut.follower_vehicle”,“intervalType”:“MatchIntervalData”,“childrenFilter”:null,“intervalCriteria”:}],“logicalOperator”:“AND”,“isEmpty”:false}],“timeRelation”:“ANY_INTERSECTION”,“customTimeRelation”:null,“workspaceId”:“4a4cafc9c441ec77fc08”},“temporalAction”:“UNION”,“nameParams”:{“name”:“test_interval”,“concatNames”:false,“delimiter”:“_”},“metricGroupPrefix”:null,“corrMetricGroupPrefix”:null},“creationContext”:“WORKSPACE”,“createdAt”:1762683706},“414981a5b9d77c76829a”:{“id”:“414981a5b9d77c76829a”,“name”:“test_rule_1”,“modifiedAt”:1762683707,“lastModifiedById”:“42e6b2f773365a5fae82”,“createdById”:“42e6b2f773365a5fae82”,“rulesParams”:{“temporalRelationParams”:{“intervalFilters”:[{“elements”:[{“_type”:“intervals”,“include”:true,“scenarioName”:null,“protected”:false,“logicalOperator”:“AND”,“intervalName”:“sut.lead_vehicle”,“intervalType”:“MatchIntervalData”,“childrenFilter”:null,“intervalCriteria”:}],“logicalOperator”:“AND”,“isEmpty”:false},{“elements”:[{“_type”:“intervals”,“include”:true,“scenarioName”:null,“protected”:false,“logicalOperator”:“AND”,“intervalName”:“sut.follower_vehicle”,“intervalType”:“MatchIntervalData”,“childrenFilter”:null,“intervalCriteria”:}],“logicalOperator”:“AND”,“isEmpty”:false}],“timeRelation”:“ANY_INTERSECTION”,“customTimeRelation”:null,“workspaceId”:“4a4cafc9c441ec77fc08”},“temporalAction”:“UNION”,“nameParams”:{“name”:“test_interval”,“concatNames”:false,“delimiter”:“_”},“metricGroupPrefix”:null,“corrMetricGroupPrefix”:null},“creationContext”:“WORKSPACE”,“createdAt”:1762683707}}’),version=(‘2’::int4),workspace_id=(‘4a4cafc9c441ec77fc08’)
    where id=(‘4643b0cbd1fce539cc70’)]
    
    however, if looking at the postgresql log message exactly at that timestamp
    we will see that the order of elements is reversed
    (note the order of "test_rule_1" and "test_rule_0")
    
    2025-11-09 12:21:47.140 IST [3182906] fmanager@fmanager LOG: execute : /*
    update for
    com.foretellix.manager.services.workspace.WorkspaceCompoundRulesData
    */update workspace_compound_rules set
    compound_rules=$1,version=$2,workspace_id=$3 where id=$4
    
    2025-11-09 12:21:47.140 IST [3182906] fmanager@fmanager DETAIL: parameters:
    $1 = ‘{“414981a5b9d77c76829a”: {“id”: “414981a5b9d77c76829a”, “name”:
    “test_rule_1”, “createdAt”: 1762683707, “modifiedAt”: 1762683707,
    “createdById”: “42e6b2f773365a5fae82”, “rulesParams”: {“nameParams”:
    {“name”: “test_interval”, “delimiter”: “_”, “concatNames”: false},
    “temporalAction”: “UNION”, “metricGroupPrefix”: null,
    “corrMetricGroupPrefix”: null, “temporalRelationParams”: {“workspaceId”:
    “4a4cafc9c441ec77fc08”, “timeRelation”: “ANY_INTERSECTION”,
    “intervalFilters”: [{“isEmpty”: false, “elements”: [{“_type”: “intervals”,
    “include”: true, “protected”: false, “intervalName”: “sut.lead_vehicle”,
    “intervalType”: “MatchIntervalData”, “scenarioName”: null, “childrenFilter”:
    null, “logicalOperator”: “AND”, “intervalCriteria”: }], “logicalOperator”:
    “AND”}, {“isEmpty”: false, “elements”: [{“_type”: “intervals”, “include”:
    true, “protected”: false, “intervalName”: “sut.follower_vehicle”,
    “intervalType”: “MatchIntervalData”, “scenarioName”: null, “childrenFilter”:
    null, “logicalOperator”: “AND”, “intervalCriteria”: }], “logicalOperator”:
    “AND”}], “customTimeRelation”: null}}, “creationContext”: “WORKSPACE”,
    “lastModifiedById”: “42e6b2f773365a5fae82”}, “4d3f85b4962c50fd7f38”: {“id”:
    “4d3f85b4962c50fd7f38”, “name”: “test_rule_0”, “createdAt”: 1762683706,
    “modifiedAt”: 1762683706, “createdById”: “42e6b2f773365a5fae82”,
    “rulesParams”: {“nameParams”: {“name”: “test_interval”, “delimiter”: “_”,
    “concatNames”: false}, “temporalAction”: “UNION”, “metricGroupPrefix”: null,
    “corrMetricGroupPrefix”: null, “temporalRelationParams”: {“workspaceId”:
    “4a4cafc9c441ec77fc08”, “timeRelation”: “ANY_INTERSECTION”,
    “intervalFilters”: [{“isEmpty”: false, “elements”: [{“_type”: “intervals”,
    “include”: true, “protected”: false, “intervalName”: “sut.lead_vehicle”,
    “intervalType”: “MatchIntervalData”, “scenarioName”: null, “childrenFilter”:
    null, “logicalOperator”: “AND”, “intervalCriteria”: }], “logicalOperator”:
    “AND”}, {“isEmpty”: false, “elements”: [{“_type”: “intervals”, “include”:
    true, “protected”: false, “intervalName”: “sut.follower_vehicle”,
    “intervalType”: “MatchIntervalData”, “scenarioName”: null, “childrenFilter”:
    null, “logicalOperator”: “AND”, “intervalCriteria”: }], “logicalOperator”:
    “AND”}], “customTimeRelation”: null}}, “creationContext”: “WORKSPACE”,
    “lastModifiedById”: “42e6b2f773365a5fae82”}}’, $2 = ‘2’, $3 =
    ‘4a4cafc9c441ec77fc08’, $4 = ‘4643b0cbd1fce539cc70’
    
    
    can you shed some light on what causing this ?  it seems that in the
    postgres side there is a ordering of elements based on the "id" lexical
    value
    
    thanks
    Tal