Hello!
While I was testing a migration query on our development database I have found a unexpected behaviour.
Here is a simplified example:
SELECT * FROM `Test`.`_default`.`_default`
[
{
"_default": {
"ID": "key-1",
"history": [
{
"subID": "sub1",
"timestamp": 1
}
]
}
},
{
"_default": {
"ID": "key-2",
"history": [
{
"subID": "sub1",
"timestamp": 1
},
{
"subID": "sub2",
"timestamp": 2
}
]
}
},
{
"_default": {
"ID": "key-3",
"history": [
{
"subID": "sub1",
"timestamp": 1
},
{
"subID": "sub2",
"timestamp": 2
},
{
"subID": "sub3",
"timestamp": 3
}
]
}
}
]
My intention is the following:
- Create a new object called “nest” in each history entry.
- Add a “type” field into the “nest” objects with a fixed string value.
- Move the “subID” field into the “nest” object
My initial idea was the following:
UPDATE `Test`.`_default`.`_default`
SET s.`nest` = {} FOR s IN `history` END, s.`nest`.`subID` = s.`subID` FOR s IN `history` END, s.`nest`.`type` = "some-type" FOR s IN `history` END
UNSET s.`subID` FOR s IN `history` END
RETURNING *
[
{
"_default": {
"ID": "key-1",
"history": [
{
"nest": {
"subID": "sub1",
"type": "some-type"
},
"timestamp": 1
}
]
}
},
{
"_default": {
"ID": "key-2",
"history": [
{
"nest": {
"subID": "sub2",
"type": "some-type"
},
"timestamp": 1
},
{
"nest": {
"subID": "sub2",
"type": "some-type"
},
"timestamp": 2
}
]
}
},
{
"_default": {
"ID": "key-3",
"history": [
{
"nest": {
"subID": "sub3",
"type": "some-type"
},
"timestamp": 1
},
{
"nest": {
"subID": "sub3",
"type": "some-type"
},
"timestamp": 2
},
{
"nest": {
"subID": "sub3",
"type": "some-type"
},
"timestamp": 3
}
]
}
}
]
As you can see “subID” field is somehow only evaluated once and its value is cached for the following updates in the list. As far as I can see, this behaviour is not documented and possibly not intended either. In the documentation only static values are used on the right side of the assigment.
After some testing I have found I way to do what I wanted:
UPDATE `Test`.`_default`.`_default`
SET s.`nest` = OBJECT_PUT({"type": "some-type"}, "subID", s.`subID`) FOR s IN `history` END
UNSET s.`subID` FOR s IN `history` END
RETURNING *
[
{
"_default": {
"ID": "key-1",
"history": [
{
"nest": {
"subID": "sub1",
"type": "some-type"
},
"timestamp": 1
}
]
}
},
{
"_default": {
"ID": "key-2",
"history": [
{
"nest": {
"subID": "sub1",
"type": "some-type"
},
"timestamp": 1
},
{
"nest": {
"subID": "sub2",
"type": "some-type"
},
"timestamp": 2
}
]
}
},
{
"_default": {
"ID": "key-3",
"history": [
{
"nest": {
"subID": "sub1",
"type": "some-type"
},
"timestamp": 1
},
{
"nest": {
"subID": "sub2",
"type": "some-type"
},
"timestamp": 2
},
{
"nest": {
"subID": "sub3",
"type": "some-type"
},
"timestamp": 3
}
]
}
}
]
My guess is that this works, because the right side is a function and the return value is not cached.