blob: f551c4b82369ca11d7f2bc293630a9686026222e [file] [log] [blame]
drh852944e2015-09-10 03:29:11 +00001# 2015-08-12
2#
3# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
5#
6# May you do good and not evil.
7# May you find forgiveness for yourself and forgive others.
8# May you share freely, never taking more than you give.
9#
10#***********************************************************************
11# This file implements tests for JSON SQL functions extension to the
12# SQLite library.
13#
14# This file contains tests automatically generated from the json1
15# documentation.
16#
17
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
drh852944e2015-09-10 03:29:11 +000021do_execsql_test json102-100 {
drhe98b6fa2015-09-11 15:32:33 +000022 SELECT json_object('ex','[52,3.14159]');
23} {{{"ex":"[52,3.14159]"}}}
24do_execsql_test json102-110 {
25 SELECT json_object('ex',json('[52,3.14159]'));
26} {{{"ex":[52,3.14159]}}}
27do_execsql_test json102-120 {
28 SELECT json_object('ex',json_array(52,3.14159));
29} {{{"ex":[52,3.14159]}}}
30do_execsql_test json102-130 {
drh12b3b892015-09-11 01:22:41 +000031 SELECT json(' { "this" : "is", "a": [ "test" ] } ');
32} {{{"this":"is","a":["test"]}}}
drhe98b6fa2015-09-11 15:32:33 +000033do_execsql_test json102-140 {
drh852944e2015-09-10 03:29:11 +000034 SELECT json_array(1,2,'3',4);
35} {{[1,2,"3",4]}}
drhe98b6fa2015-09-11 15:32:33 +000036do_execsql_test json102-150 {
drh852944e2015-09-10 03:29:11 +000037 SELECT json_array('[1,2]');
38} {{["[1,2]"]}}
drhe98b6fa2015-09-11 15:32:33 +000039do_execsql_test json102-160 {
drh12b3b892015-09-11 01:22:41 +000040 SELECT json_array(json_array(1,2));
41} {{[[1,2]]}}
drhe98b6fa2015-09-11 15:32:33 +000042do_execsql_test json102-170 {
drh852944e2015-09-10 03:29:11 +000043 SELECT json_array(1,null,'3','[4,5]','{"six":7.7}');
44} {{[1,null,"3","[4,5]","{\"six\":7.7}"]}}
drhe98b6fa2015-09-11 15:32:33 +000045do_execsql_test json102-180 {
drh12b3b892015-09-11 01:22:41 +000046 SELECT json_array(1,null,'3',json('[4,5]'),json('{"six":7.7}'));
47} {{[1,null,"3",[4,5],{"six":7.7}]}}
drhe98b6fa2015-09-11 15:32:33 +000048do_execsql_test json102-190 {
drh852944e2015-09-10 03:29:11 +000049 SELECT json_array_length('[1,2,3,4]');
50} {{4}}
drhe98b6fa2015-09-11 15:32:33 +000051do_execsql_test json102-200 {
52 SELECT json_array_length('[1,2,3,4]', '$');
53} {{4}}
54do_execsql_test json102-210 {
55 SELECT json_array_length('[1,2,3,4]', '$[2]');
56} {{0}}
57do_execsql_test json102-220 {
drh852944e2015-09-10 03:29:11 +000058 SELECT json_array_length('{"one":[1,2,3]}');
59} {{0}}
drhe98b6fa2015-09-11 15:32:33 +000060do_execsql_test json102-230 {
drh852944e2015-09-10 03:29:11 +000061 SELECT json_array_length('{"one":[1,2,3]}', '$.one');
62} {{3}}
drh12b3b892015-09-11 01:22:41 +000063do_execsql_test json102-240 {
drhe98b6fa2015-09-11 15:32:33 +000064 SELECT json_array_length('{"one":[1,2,3]}', '$.two');
drh852944e2015-09-10 03:29:11 +000065} {{}}
drh12b3b892015-09-11 01:22:41 +000066do_execsql_test json102-250 {
drhe98b6fa2015-09-11 15:32:33 +000067 SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$');
68} {{{"a":2,"c":[4,5,{"f":7}]}}}
69do_execsql_test json102-260 {
70 SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c');
71} {{[4,5,{"f":7}]}}
72do_execsql_test json102-270 {
73 SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2]');
74} {{{"f":7}}}
75do_execsql_test json102-280 {
76 SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2].f');
77} {{7}}
78do_execsql_test json102-290 {
79 SELECT json_extract('{"a":2,"c":[4,5],"f":7}','$.c','$.a');
80} {{[[4,5],2]}}
81do_execsql_test json102-300 {
82 SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x');
83} {{}}
84do_execsql_test json102-310 {
85 SELECT json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x', '$.a');
86} {{[null,2]}}
87do_execsql_test json102-320 {
drh852944e2015-09-10 03:29:11 +000088 SELECT json_insert('{"a":2,"c":4}', '$.a', 99);
89} {{{"a":2,"c":4}}}
drhe98b6fa2015-09-11 15:32:33 +000090do_execsql_test json102-330 {
drh852944e2015-09-10 03:29:11 +000091 SELECT json_insert('{"a":2,"c":4}', '$.e', 99);
92} {{{"a":2,"c":4,"e":99}}}
drhe98b6fa2015-09-11 15:32:33 +000093do_execsql_test json102-340 {
drh852944e2015-09-10 03:29:11 +000094 SELECT json_replace('{"a":2,"c":4}', '$.a', 99);
95} {{{"a":99,"c":4}}}
drhe98b6fa2015-09-11 15:32:33 +000096do_execsql_test json102-350 {
drh852944e2015-09-10 03:29:11 +000097 SELECT json_replace('{"a":2,"c":4}', '$.e', 99);
98} {{{"a":2,"c":4}}}
drhe98b6fa2015-09-11 15:32:33 +000099do_execsql_test json102-360 {
drh852944e2015-09-10 03:29:11 +0000100 SELECT json_set('{"a":2,"c":4}', '$.a', 99);
101} {{{"a":99,"c":4}}}
drhe98b6fa2015-09-11 15:32:33 +0000102do_execsql_test json102-370 {
drh852944e2015-09-10 03:29:11 +0000103 SELECT json_set('{"a":2,"c":4}', '$.e', 99);
104} {{{"a":2,"c":4,"e":99}}}
drhe98b6fa2015-09-11 15:32:33 +0000105do_execsql_test json102-380 {
drh12b3b892015-09-11 01:22:41 +0000106 SELECT json_set('{"a":2,"c":4}', '$.c', '[97,96]');
107} {{{"a":2,"c":"[97,96]"}}}
drhe98b6fa2015-09-11 15:32:33 +0000108do_execsql_test json102-390 {
drh12b3b892015-09-11 01:22:41 +0000109 SELECT json_set('{"a":2,"c":4}', '$.c', json('[97,96]'));
110} {{{"a":2,"c":[97,96]}}}
drhe98b6fa2015-09-11 15:32:33 +0000111do_execsql_test json102-400 {
drh12b3b892015-09-11 01:22:41 +0000112 SELECT json_set('{"a":2,"c":4}', '$.c', json_array(97,96));
113} {{{"a":2,"c":[97,96]}}}
drhe98b6fa2015-09-11 15:32:33 +0000114do_execsql_test json102-410 {
drh852944e2015-09-10 03:29:11 +0000115 SELECT json_object('a',2,'c',4);
116} {{{"a":2,"c":4}}}
drhe98b6fa2015-09-11 15:32:33 +0000117do_execsql_test json102-420 {
drh852944e2015-09-10 03:29:11 +0000118 SELECT json_object('a',2,'c','{e:5}');
119} {{{"a":2,"c":"{e:5}"}}}
drhe98b6fa2015-09-11 15:32:33 +0000120do_execsql_test json102-430 {
drh12b3b892015-09-11 01:22:41 +0000121 SELECT json_object('a',2,'c',json_object('e',5));
122} {{{"a":2,"c":{"e":5}}}}
drhe98b6fa2015-09-11 15:32:33 +0000123do_execsql_test json102-440 {
drh852944e2015-09-10 03:29:11 +0000124 SELECT json_remove('[0,1,2,3,4]','$[2]');
125} {{[0,1,3,4]}}
drhe98b6fa2015-09-11 15:32:33 +0000126do_execsql_test json102-450 {
drh852944e2015-09-10 03:29:11 +0000127 SELECT json_remove('[0,1,2,3,4]','$[2]','$[0]');
128} {{[1,3,4]}}
drhe98b6fa2015-09-11 15:32:33 +0000129do_execsql_test json102-460 {
drh852944e2015-09-10 03:29:11 +0000130 SELECT json_remove('[0,1,2,3,4]','$[0]','$[2]');
131} {{[1,2,4]}}
drhe98b6fa2015-09-11 15:32:33 +0000132do_execsql_test json102-470 {
drh852944e2015-09-10 03:29:11 +0000133 SELECT json_remove('{"x":25,"y":42}');
134} {{{"x":25,"y":42}}}
drhe98b6fa2015-09-11 15:32:33 +0000135do_execsql_test json102-480 {
drh852944e2015-09-10 03:29:11 +0000136 SELECT json_remove('{"x":25,"y":42}','$.z');
137} {{{"x":25,"y":42}}}
drhe98b6fa2015-09-11 15:32:33 +0000138do_execsql_test json102-490 {
drh852944e2015-09-10 03:29:11 +0000139 SELECT json_remove('{"x":25,"y":42}','$.y');
140} {{{"x":25}}}
drhe98b6fa2015-09-11 15:32:33 +0000141do_execsql_test json102-500 {
drh852944e2015-09-10 03:29:11 +0000142 SELECT json_remove('{"x":25,"y":42}','$');
143} {{}}
drhe98b6fa2015-09-11 15:32:33 +0000144do_execsql_test json102-510 {
drh852944e2015-09-10 03:29:11 +0000145 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}');
146} {{object}}
drhe98b6fa2015-09-11 15:32:33 +0000147do_execsql_test json102-520 {
drh852944e2015-09-10 03:29:11 +0000148 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$');
149} {{object}}
drhe98b6fa2015-09-11 15:32:33 +0000150do_execsql_test json102-530 {
drh852944e2015-09-10 03:29:11 +0000151 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a');
152} {{array}}
drhe98b6fa2015-09-11 15:32:33 +0000153do_execsql_test json102-540 {
drh852944e2015-09-10 03:29:11 +0000154 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[0]');
155} {{integer}}
drhe98b6fa2015-09-11 15:32:33 +0000156do_execsql_test json102-550 {
drh852944e2015-09-10 03:29:11 +0000157 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[1]');
158} {{real}}
drhe98b6fa2015-09-11 15:32:33 +0000159do_execsql_test json102-560 {
drh852944e2015-09-10 03:29:11 +0000160 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[2]');
161} {{true}}
drhe98b6fa2015-09-11 15:32:33 +0000162do_execsql_test json102-570 {
drh852944e2015-09-10 03:29:11 +0000163 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[3]');
164} {{false}}
drhe98b6fa2015-09-11 15:32:33 +0000165do_execsql_test json102-580 {
drh852944e2015-09-10 03:29:11 +0000166 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[4]');
167} {{null}}
drhe98b6fa2015-09-11 15:32:33 +0000168do_execsql_test json102-590 {
drh852944e2015-09-10 03:29:11 +0000169 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[5]');
170} {{text}}
drhe98b6fa2015-09-11 15:32:33 +0000171do_execsql_test json102-600 {
drh852944e2015-09-10 03:29:11 +0000172 SELECT json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[6]');
173} {{}}
drhe98b6fa2015-09-11 15:32:33 +0000174do_execsql_test json102-610 {
drh12b3b892015-09-11 01:22:41 +0000175 SELECT json_valid(char(123)||'"x":35'||char(125));
drh852944e2015-09-10 03:29:11 +0000176} {{1}}
drhe98b6fa2015-09-11 15:32:33 +0000177do_execsql_test json102-620 {
drh12b3b892015-09-11 01:22:41 +0000178 SELECT json_valid(char(123)||'"x":35');
drh852944e2015-09-10 03:29:11 +0000179} {{0}}
180
drhe6f52782015-09-10 15:22:35 +0000181ifcapable vtab {
drh12b3b892015-09-11 01:22:41 +0000182do_execsql_test json102-1000 {
drh852944e2015-09-10 03:29:11 +0000183 CREATE TABLE user(name,phone);
184 INSERT INTO user(name,phone) VALUES
185 ('Alice','["919-555-2345","804-555-3621"]'),
186 ('Bob','["201-555-8872"]'),
187 ('Cindy','["704-555-9983"]'),
188 ('Dave','["336-555-8421","704-555-4321","803-911-4421"]');
189 SELECT DISTINCT user.name
190 FROM user, json_each(user.phone)
191 WHERE json_each.value LIKE '704-%'
192 ORDER BY 1;
193} {Cindy Dave}
194
drh12b3b892015-09-11 01:22:41 +0000195do_execsql_test json102-1010 {
drh852944e2015-09-10 03:29:11 +0000196 UPDATE user
197 SET phone=json_extract(phone,'$[0]')
198 WHERE json_array_length(phone)<2;
199 SELECT name, substr(phone,1,5) FROM user ORDER BY name;
200} {Alice {["919} Bob 201-5 Cindy 704-5 Dave {["336}}
drh12b3b892015-09-11 01:22:41 +0000201do_execsql_test json102-1011 {
drh852944e2015-09-10 03:29:11 +0000202 SELECT name FROM user WHERE phone LIKE '704-%'
203 UNION
204 SELECT user.name
205 FROM user, json_each(user.phone)
206 WHERE json_valid(user.phone)
207 AND json_each.value LIKE '704-%';
208} {Cindy Dave}
209
drh12b3b892015-09-11 01:22:41 +0000210do_execsql_test json102-1100 {
drh852944e2015-09-10 03:29:11 +0000211 CREATE TABLE big(json JSON);
212 INSERT INTO big(json) VALUES('{
213 "id":123,
214 "stuff":[1,2,3,4],
215 "partlist":[
216 {"uuid":"bb108722-572e-11e5-9320-7f3b63a4ca74"},
217 {"uuid":"c690dc14-572e-11e5-95f9-dfc8861fd535"},
218 {"subassembly":[
219 {"uuid":"6fa5181e-5721-11e5-a04e-57f3d7b32808"}
220 ]}
221 ]
222 }');
223 INSERT INTO big(json) VALUES('{
224 "id":456,
225 "stuff":["hello","world","xyzzy"],
226 "partlist":[
227 {"uuid":false},
228 {"uuid":"c690dc14-572e-11e5-95f9-dfc8861fd535"}
229 ]
230 }');
231} {}
232set correct_answer [list \
233 1 {$.id} 123 \
234 1 {$.stuff[0]} 1 \
235 1 {$.stuff[1]} 2 \
236 1 {$.stuff[2]} 3 \
237 1 {$.stuff[3]} 4 \
238 1 {$.partlist[0].uuid} bb108722-572e-11e5-9320-7f3b63a4ca74 \
239 1 {$.partlist[1].uuid} c690dc14-572e-11e5-95f9-dfc8861fd535 \
240 1 {$.partlist[2].subassembly[0].uuid} 6fa5181e-5721-11e5-a04e-57f3d7b32808 \
241 2 {$.id} 456 \
242 2 {$.stuff[0]} hello \
243 2 {$.stuff[1]} world \
244 2 {$.stuff[2]} xyzzy \
245 2 {$.partlist[0].uuid} 0 \
246 2 {$.partlist[1].uuid} c690dc14-572e-11e5-95f9-dfc8861fd535]
drh12b3b892015-09-11 01:22:41 +0000247do_execsql_test json102-1110 {
drh852944e2015-09-10 03:29:11 +0000248 SELECT big.rowid, fullkey, value
249 FROM big, json_tree(big.json)
250 WHERE json_tree.type NOT IN ('object','array')
251 ORDER BY +big.rowid, +json_tree.id
252} $correct_answer
drh12b3b892015-09-11 01:22:41 +0000253do_execsql_test json102-1120 {
drh852944e2015-09-10 03:29:11 +0000254 SELECT big.rowid, fullkey, atom
255 FROM big, json_tree(big.json)
256 WHERE atom IS NOT NULL
257 ORDER BY +big.rowid, +json_tree.id
258} $correct_answer
259
drh12b3b892015-09-11 01:22:41 +0000260do_execsql_test json102-1130 {
drh852944e2015-09-10 03:29:11 +0000261 SELECT DISTINCT json_extract(big.json,'$.id')
262 FROM big, json_tree(big.json,'$.partlist')
263 WHERE json_tree.key='uuid'
264 AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808';
265} {123}
drh12b3b892015-09-11 01:22:41 +0000266do_execsql_test json102-1131 {
drh852944e2015-09-10 03:29:11 +0000267 SELECT DISTINCT json_extract(big.json,'$.id')
268 FROM big, json_tree(big.json,'$')
269 WHERE json_tree.key='uuid'
270 AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808';
271} {123}
drh12b3b892015-09-11 01:22:41 +0000272do_execsql_test json102-1132 {
drh852944e2015-09-10 03:29:11 +0000273 SELECT DISTINCT json_extract(big.json,'$.id')
274 FROM big, json_tree(big.json)
275 WHERE json_tree.key='uuid'
276 AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808';
277} {123}
drhe6f52782015-09-10 15:22:35 +0000278} ;# end ifcapable vtab
drh852944e2015-09-10 03:29:11 +0000279
dan2e8f5512015-09-17 17:21:09 +0000280#-------------------------------------------------------------------------
281# Test that json_valid() correctly identifies non-ascii range
282# characters as non-whitespace.
283#
284do_execsql_test json102-1201 { SELECT json_valid(char(32) || '"xyz"') } 1
285do_execsql_test json102-1202 { SELECT json_valid(char(200) || '"xyz"') } 0
286
drh4977ccf2015-09-19 11:57:26 +0000287# Off-by-one error in jsonAppendString()
288#
289for {set i 0} {$i<100} {incr i} {
290 set str abcdef[string repeat \" [expr {$i+50}]]uvwxyz
291 do_test json102-[format %d [expr {$i+1300}]] {
292 db eval {SELECT json_extract(json_array($::str),'$[0]')==$::str}
293 } {1}
294}
295
drh9fa866a2017-04-08 18:18:22 +0000296#-------------------------------------------------------------------------
297# 2017-04-08 ticket b93be8729a895a528e2849fca99f7
298# JSON extension accepts invalid numeric values
299#
300# JSON does not allow leading zeros. But the JSON extension was
301# allowing them. The following tests verify that the problem is now
302# fixed.
303#
304do_execsql_test json102-1401 { SELECT json_valid('{"x":01}') } 0
305do_execsql_test json102-1402 { SELECT json_valid('{"x":-01}') } 0
306do_execsql_test json102-1403 { SELECT json_valid('{"x":0}') } 1
307do_execsql_test json102-1404 { SELECT json_valid('{"x":-0}') } 1
308do_execsql_test json102-1405 { SELECT json_valid('{"x":0.1}') } 1
309do_execsql_test json102-1406 { SELECT json_valid('{"x":-0.1}') } 1
310do_execsql_test json102-1407 { SELECT json_valid('{"x":0.0000}') } 1
311do_execsql_test json102-1408 { SELECT json_valid('{"x":-0.0000}') } 1
312do_execsql_test json102-1409 { SELECT json_valid('{"x":01.5}') } 0
313do_execsql_test json102-1410 { SELECT json_valid('{"x":-01.5}') } 0
314do_execsql_test json102-1411 { SELECT json_valid('{"x":00}') } 0
315do_execsql_test json102-1412 { SELECT json_valid('{"x":-00}') } 0
316
drhe12e24d2017-04-10 12:25:05 +0000317#------------------------------------------------------------------------
318# 2017-04-10 ticket 6c9b5514077fed34551f98e64c09a10dc2fc8e16
319# JSON extension accepts strings containing control characters.
320#
321# The JSON spec requires that all control characters be escaped.
322#
323do_execsql_test json102-1500 {
324 WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<0x20)
325 SELECT x FROM c WHERE json_valid(printf('{"a":"x%sz"}', char(x))) ORDER BY x;
326} {32}
327
drh2ac702d2017-04-10 12:31:15 +0000328# All control characters are escaped
329#
330do_execsql_test json102-1501 {
331 WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<0x1f)
332 SELECT sum(json_valid(json_quote('a'||char(x)||'z'))) FROM c ORDER BY x;
333} {31}
334
drhd83c90b2022-01-10 15:43:13 +0000335# 2022-01-10 tests for -> and ->> operators
336#
337reset_db
338do_execsql_test json102-1600 {
339 CREATE TABLE t1(id INTEGER PRIMARY KEY, x JSON);
340 INSERT INTO t1(id,x) VALUES
341 (1, '{"a":null}'),
342 (2, '{"a":123}'),
343 (3, '{"a":4.5}'),
344 (4, '{"a":"six"}'),
345 (5, '{"a":[7,8]}'),
346 (6, '{"a":{"b":9}}'),
347 (7, '{"b":999}');
348 SELECT
349 id,
350 x->'a' AS '->',
351 CASE WHEN subtype(x->'a') THEN 'json' ELSE typeof(x->'a') END AS 'type',
352 x->>'a' AS '->>',
353 CASE WHEN subtype(x->>'a') THEN 'json' ELSE typeof(x->>'a') END AS 'type',
354 json_extract(x,'$.a') AS 'json_extract',
355 CASE WHEN subtype(json_extract(x,'$.a'))
356 THEN 'json' ELSE typeof(json_extract(x,'$.a')) END AS 'type'
357 FROM t1 ORDER BY id;
358} [list \
359 1 null json {} null {} null \
360 2 123 json 123 integer 123 integer \
361 3 4.5 json 4.5 real 4.5 real \
362 4 {"six"} json six text six text \
363 5 {[7,8]} json {[7,8]} text {[7,8]} json \
364 6 {{"b":9}} json {{"b":9}} text {{"b":9}} json \
365 7 {} null {} null {} null
366]
367do_execsql_test json102-1610 {
368 DELETE FROM t1;
369 INSERT INTO t1(x) VALUES('[null,123,4.5,"six",[7,8],{"b":9}]');
370 WITH c(y) AS (VALUES(0),(1),(2),(3),(4),(5),(6))
371 SELECT
372 y,
373 x->y AS '->',
374 CASE WHEN subtype(x->y) THEN 'json' ELSE typeof(x->y) END AS 'type',
375 x->>y AS '->>',
376 CASE WHEN subtype(x->>y) THEN 'json' ELSE typeof(x->>y) END AS 'type',
377 json_extract(x,format('$[%d]',y)) AS 'json_extract',
378 CASE WHEN subtype(json_extract(x,format('$[%d]',y)))
379 THEN 'json' ELSE typeof(json_extract(x,format('$[%d]',y))) END AS 'type'
380 FROM c, t1 ORDER BY y;
381} [list \
382 0 null json {} null {} null \
383 1 123 json 123 integer 123 integer \
384 2 4.5 json 4.5 real 4.5 real \
385 3 {"six"} json six text six text \
386 4 {[7,8]} json {[7,8]} text {[7,8]} json \
387 5 {{"b":9}} json {{"b":9}} text {{"b":9}} json \
388 6 {} null {} null {} null
389]
390
drh852944e2015-09-10 03:29:11 +0000391finish_test