1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
-- test-run result file version 2
--
-- gh-5135: there was a crash in case upsert operation was
-- invalid with an error appeared not in the operation, but in
-- something else. For example, bad json. Or json type mismatching
-- field type (attempt to do [...] on a scalar field). The
-- expected behaviour is that such operations are just skipped.
-- All the crashes were related to a so called 'bar' update. When
-- an operation has a json path not interleaving with any other
-- path.
-- In all tests no crash should happen + not less importantly the
-- bad operation should be nop, and should not affect other
-- operations.
--
ops = {}
| ---
| ...
ops[1] = {'!', 1, 1}
| ---
| ...
ops[3] = {'!', 3, 2}
| ---
| ...
-- Duplicate in a map.
t = box.tuple.new({{a = 100}})
| ---
| ...
ops[2] = {'!', '[1].a', 200}
| ---
| ...
t:upsert(ops)
| ---
| - [1, {'a': 100}, 2]
| ...
-- Bad JSON when do '!'.
ops[2] = {'!', '[1].a[crash]', 200}
| ---
| ...
t:upsert(ops)
| ---
| - [1, {'a': 100}, 2]
| ...
-- Bad JSON when do '='.
t = box.tuple.new({{1}})
| ---
| ...
ops[2] = {'!', '[1][crash]', 200}
| ---
| ...
t:upsert(ops)
| ---
| - [1, [1], 2]
| ...
-- Can't delete more than 1 field from map in one
-- operation.
t = box.tuple.new({{a = 100}})
| ---
| ...
ops[2] = {'#', '[1].a', 2}
| ---
| ...
t:upsert(ops)
| ---
| - [1, {'a': 100}, 2]
| ...
-- Bad JSON in '#'
ops[2] = {'#', '[1].a[crash]', 1}
| ---
| ...
t:upsert(ops)
| ---
| - [1, {'a': 100}, 2]
| ...
-- Bad JSON in scalar operations.
ops[2] = {'+', '[1].a[crash]', 1}
| ---
| ...
t:upsert(ops)
| ---
| - [1, {'a': 100}, 2]
| ...
t = box.tuple.new({{1}})
| ---
| ...
ops[2] = {'&', '[1][crash]', 2}
| ---
| ...
t:upsert(ops)
| ---
| - [1, [1], 2]
| ...
-- Several fields, multiple operations, path
-- interleaving.
t = box.tuple.new({{1}, {2}})
| ---
| ...
t:upsert({{'+', '[2][1]', 1}, {'&', '[1][crash]', 2}, {'=', '[3]', {4}}})
| ---
| - [[1], [3], [4]]
| ...
t = box.tuple.new({ { { { 1 } }, { {a = 2} } }, { 3 } })
| ---
| ...
t:upsert({{'=', '[1][1][1]', 4}, {'!', '[1][2][1].a', 5}, {'-', '[2][1]', 4}})
| ---
| - [[[4], [{'a': 2}]], [-1]]
| ...
-- A valid operation on top of invalid, for the
-- same field.
t:upsert({{'+', '[1][1][1].a', 10}, {'+', '[1][1][1]', -10}})
| ---
| - [[[[1]], [{'a': 2}]], [3]]
| ...
-- Invalid operand of an arith operation. Also should turn into
-- nop.
t:upsert({{'+', '[1][1][1]', 10}})
| ---
| - [[[[1]], [{'a': 2}]], [3]]
| ...
-- This should be correct.
t:upsert({{'+', '[1][1][1][1]', 10}})
| ---
| - [[[[11]], [{'a': 2}]], [3]]
| ...
-- Check that invalid insertion can't screw indexes. I.e. next
-- operations won't see the not added field.
t = box.tuple.new({{1, 2, 3}})
| ---
| ...
-- The second operation should change 2 to 12, not 20 to 30.
t:upsert({{'!', '[1][2][100]', 20}, {'+', '[1][2]', 10}})
| ---
| - [[1, 12, 3]]
| ...
|