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

From: PG Bug reporting form <noreply(at)postgresql(dot)org>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: tal(dot)tabakman(at)foretellix(dot)com
Subject: BUG #19110: the order of elements in a json object in database is different then the order of elements
Date: 2025-11-11 14:26:34
Message-ID: 19110-dffefa888c44b48f@postgresql.org
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The following bug has been logged on the website:

Bug reference: 19110
Logged by: Tal Tabakman
Email address: tal(dot)tabakman(at)foretellix(dot)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(at)fmanager(dot)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(at)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(at)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

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2025-11-11 15:16:03 Re: BUG #19110: the order of elements in a json object in database is different then the order of elements
Previous Message hubert depesz lubaczewski 2025-11-11 12:43:53 Re: Functions used by index don't need to be immutable?