Thanks to visit codestin.com
Credit goes to chromium.googlesource.com

blob: 3078be34bac92634a49f30095bab3251ad4f9c04 [file] [log] [blame]
drh5fa5c102015-08-12 16:49:401/*
2** 2015-08-12
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11******************************************************************************
12**
drha0de4542023-12-05 18:28:1513** SQLite JSON functions.
drh5fa5c102015-08-12 16:49:4014**
drh9dbf96b2022-01-06 01:40:0915** This file began as an extension in ext/misc/json1.c in 2015. That
16** extension proved so useful that it has now been moved into the core.
drh5fa5c102015-08-12 16:49:4017**
drhecce6022023-09-29 11:17:4318** The original design stored all JSON as pure text, canonical RFC-8259.
19** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16).
20** All generated JSON text still conforms strictly to RFC-8259, but text
21** with JSON-5 extensions is accepted as input.
22**
drh3262ca82023-12-19 21:39:5823** Beginning with version 3.45.0 (circa 2024-01-01), these routines also
24** accept BLOB values that have JSON encoded using a binary representation
25** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk
drh3a7042e2025-04-01 15:17:0126** format for SQLite-JSONB is completely different and incompatible with
27** PostgreSQL-JSONB.
drhecce6022023-09-29 11:17:4328**
29** Decoding and interpreting JSONB is still O(N) where N is the size of
30** the input, the same as text JSON. However, the constant of proportionality
31** for JSONB is much smaller due to faster parsing. The size of each
32** element in JSONB is encoded in its header, so there is no need to search
33** for delimiters using persnickety syntax rules. JSONB seems to be about
34** 3x faster than text JSON as a result. JSONB is also tends to be slightly
35** smaller than text JSON, by 5% or 10%, but there are corner cases where
drhae5f55e2023-09-29 12:45:1436** JSONB can be slightly larger. So you are not far mistaken to say that
37** a JSONB blob is the same size as the equivalent RFC-8259 text.
drhecce6022023-09-29 11:17:4338**
39**
40** THE JSONB ENCODING:
41**
42** Every JSON element is encoded in JSONB as a header and a payload.
43** The header is between 1 and 9 bytes in size. The payload is zero
44** or more bytes.
45**
46** The lower 4 bits of the first byte of the header determines the
47** element type:
48**
49** 0: NULL
50** 1: TRUE
51** 2: FALSE
52** 3: INT -- RFC-8259 integer literal
53** 4: INT5 -- JSON5 integer literal
54** 5: FLOAT -- RFC-8259 floating point literal
55** 6: FLOAT5 -- JSON5 floating point literal
56** 7: TEXT -- Text literal acceptable to both SQL and JSON
drhae5f55e2023-09-29 12:45:1457** 8: TEXTJ -- Text containing RFC-8259 escapes
58** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes
59** 10: TEXTRAW -- Text containing unescaped syntax characters
drhecce6022023-09-29 11:17:4360** 11: ARRAY
61** 12: OBJECT
62**
63** The other three possible values (13-15) are reserved for future
64** enhancements.
65**
66** The upper 4 bits of the first byte determine the size of the header
67** and sometimes also the size of the payload. If X is the first byte
68** of the element and if X>>4 is between 0 and 11, then the payload
69** will be that many bytes in size and the header is exactly one byte
70** in size. Other four values for X>>4 (12-15) indicate that the header
71** is more than one byte in size and that the payload size is determined
72** by the remainder of the header, interpreted as a unsigned big-endian
73** integer.
74**
75** Value of X>>4 Size integer Total header size
76** ------------- -------------------- -----------------
77** 12 1 byte (0-255) 2
78** 13 2 byte (0-65535) 3
79** 14 4 byte (0-4294967295) 5
80** 15 8 byte (0-1.8e19) 9
81**
82** The payload size need not be expressed in its minimal form. For example,
83** if the payload size is 10, the size can be expressed in any of 5 different
drh3a7042e2025-04-01 15:17:0184** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by one 0x0a byte,
drhecce6022023-09-29 11:17:4385** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by
86** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and
87** a single byte of 0x0a. The shorter forms are preferred, of course, but
88** sometimes when generating JSONB, the payload size is not known in advance
89** and it is convenient to reserve sufficient header space to cover the
90** largest possible payload size and then come back later and patch up
91** the size when it becomes known, resulting in a non-minimal encoding.
92**
93** The value (X>>4)==15 is not actually used in the current implementation
drh3a7042e2025-04-01 15:17:0194** (as SQLite is currently unable to handle BLOBs larger than about 2GB)
drhecce6022023-09-29 11:17:4395** but is included in the design to allow for future enhancements.
96**
97** The payload follows the header. NULL, TRUE, and FALSE have no payload and
98** their payload size must always be zero. The payload for INT, INT5,
99** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the
100** "..." or '...' delimiters are omitted from the various text encodings.
101** The payload for ARRAY and OBJECT is a list of additional elements that
102** are the content for the array or object. The payload for an OBJECT
103** must be an even number of elements. The first element of each pair is
104** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW.
105**
106** A valid JSONB blob consists of a single element, as described above.
107** Usually this will be an ARRAY or OBJECT element which has many more
108** elements as its content. But the overall blob is just a single element.
109**
110** Input validation for JSONB blobs simply checks that the element type
111** code is between 0 and 12 and that the total size of the element
112** (header plus payload) is the same as the size of the BLOB. If those
113** checks are true, the BLOB is assumed to be JSONB and processing continues.
114** Errors are only raised if some other miscoding is discovered during
115** processing.
drhc2eff912023-12-21 18:08:05116**
117** Additional information can be found in the doc/jsonb.md file of the
118** canonical SQLite source tree.
drh5fa5c102015-08-12 16:49:40119*/
drh9dbf96b2022-01-06 01:40:09120#ifndef SQLITE_OMIT_JSON
121#include "sqliteInt.h"
dan2e8f5512015-09-17 17:21:09122
drhae5f55e2023-09-29 12:45:14123/* JSONB element types
124*/
125#define JSONB_NULL 0 /* "null" */
126#define JSONB_TRUE 1 /* "true" */
127#define JSONB_FALSE 2 /* "false" */
128#define JSONB_INT 3 /* integer acceptable to JSON and SQL */
129#define JSONB_INT5 4 /* integer in 0x000 notation */
130#define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */
131#define JSONB_FLOAT5 6 /* float with JSON5 extensions */
132#define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */
133#define JSONB_TEXTJ 8 /* Text with JSON escapes */
134#define JSONB_TEXT5 9 /* Text with JSON-5 escape */
135#define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */
136#define JSONB_ARRAY 11 /* An array */
137#define JSONB_OBJECT 12 /* An object */
138
drhc1e85742023-12-02 20:25:36139/* Human-readable names for the JSONB values. The index for each
140** string must correspond to the JSONB_* integer above.
drhabbdbdf2023-11-24 18:44:00141*/
142static const char * const jsonbType[] = {
143 "null", "true", "false", "integer", "integer",
144 "real", "real", "text", "text", "text",
drhc1e85742023-12-02 20:25:36145 "text", "array", "object", "", "", "", ""
drhabbdbdf2023-11-24 18:44:00146};
147
drh95677942015-09-24 01:06:37148/*
149** Growing our own isspace() routine this way is twice as fast as
150** the library isspace() function, resulting in a 7% overall performance
drhae5f55e2023-09-29 12:45:14151** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os).
drh95677942015-09-24 01:06:37152*/
153static const char jsonIsSpace[] = {
drh6fe2a9a2025-04-16 17:36:26154#ifdef SQLITE_ASCII
155/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
156 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0 */
157 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
158 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */
160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */
161 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */
162 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */
163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
drhc874d602023-08-02 16:06:02164
drh6fe2a9a2025-04-16 17:36:26165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */
166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */
169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */
173#endif
174#ifdef SQLITE_EBCDIC
175/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
176 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 0 */
177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
178 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */
180 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */
181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */
182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */
183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */
184
185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */
186 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */
187 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */
188 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */
189 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */
190 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
191 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */
192 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */
193#endif
194
drh95677942015-09-24 01:06:37195};
drhca1ce772023-12-01 12:57:12196#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x])
drh95677942015-09-24 01:06:37197
drhc874d602023-08-02 16:06:02198/*
drh8eac91f2023-12-05 12:52:13199** The set of all space characters recognized by jsonIsspace().
drha0de4542023-12-05 18:28:15200** Useful as the second argument to strspn().
drh8eac91f2023-12-05 12:52:13201*/
drh6fe2a9a2025-04-16 17:36:26202#ifdef SQLITE_ASCII
drh8eac91f2023-12-05 12:52:13203static const char jsonSpaces[] = "\011\012\015\040";
drh6fe2a9a2025-04-16 17:36:26204#endif
205#ifdef SQLITE_EBCDIC
206static const char jsonSpaces[] = "\005\045\015\100";
207#endif
208
drh8eac91f2023-12-05 12:52:13209
210/*
drhc1e85742023-12-02 20:25:36211** Characters that are special to JSON. Control characters,
drhcc1a39f2023-12-12 02:31:12212** '"' and '\\' and '\''. Actually, '\'' is not special to
213** canonical JSON, but it is special in JSON-5, so we include
214** it in the set of special characters.
drhc874d602023-08-02 16:06:02215*/
216static const char jsonIsOk[256] = {
drh6fe2a9a2025-04-16 17:36:26217#ifdef SQLITE_ASCII
218/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
221 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */
222 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */
223 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */
224 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 5 */
225 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
226 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
drhc874d602023-08-02 16:06:02227
drh6fe2a9a2025-04-16 17:36:26228 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */
229 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */
230 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */
231 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */
232 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */
233 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */
234 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
235 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */
236#endif
237#ifdef SQLITE_EBCDIC
238/*0 1 2 3 4 5 6 7 8 9 a b c d e f */
239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */
240 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */
242 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 3 */
243 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */
244 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */
245 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
246 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, /* 7 */
247
248 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */
249 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */
250 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */
251 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */
252 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */
253 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */
254 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
255 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */
256#endif
drhc874d602023-08-02 16:06:02257};
258
drh52216ad2015-08-18 02:28:03259/* Objects */
drhca1ce772023-12-01 12:57:12260typedef struct JsonCache JsonCache;
drh505ad2c2015-08-21 17:33:11261typedef struct JsonString JsonString;
drh52216ad2015-08-18 02:28:03262typedef struct JsonParse JsonParse;
263
drhca1ce772023-12-01 12:57:12264/*
265** Magic number used for the JSON parse cache in sqlite3_get_auxdata()
266*/
267#define JSON_CACHE_ID (-429938) /* Cache entry */
268#define JSON_CACHE_SIZE 4 /* Max number of cache entries */
269
drhb2b74902023-12-26 13:20:57270/*
271** jsonUnescapeOneChar() returns this invalid code point if it encounters
272** a syntax error.
273*/
274#define JSON_INVALID_CHAR 0x99999
275
drhca1ce772023-12-01 12:57:12276/* A cache mapping JSON text into JSONB blobs.
277**
drhc1e85742023-12-02 20:25:36278** Each cache entry is a JsonParse object with the following restrictions:
279**
280** * The bReadOnly flag must be set
281**
282** * The aBlob[] array must be owned by the JsonParse object. In other
283** words, nBlobAlloc must be non-zero.
284**
drh3262ca82023-12-19 21:39:58285** * eEdit and delta must be zero.
286**
drhc1e85742023-12-02 20:25:36287** * zJson must be an RCStr. In other words bJsonIsRCStr must be true.
drhca1ce772023-12-01 12:57:12288*/
drhca1ce772023-12-01 12:57:12289struct JsonCache {
drh063d0d42023-12-01 18:46:14290 sqlite3 *db; /* Database connection */
291 int nUsed; /* Number of active entries in the cache */
292 JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */
drhca1ce772023-12-01 12:57:12293};
294
drh5634cc02015-08-17 11:28:03295/* An instance of this object represents a JSON string
296** under construction. Really, this is a generic string accumulator
297** that can be and is used to create strings other than JSON.
drhc1e85742023-12-02 20:25:36298**
299** If the generated string is longer than will fit into the zSpace[] buffer,
300** then it will be an RCStr string. This aids with caching of large
301** JSON strings.
drh5fa5c102015-08-12 16:49:40302*/
drh505ad2c2015-08-21 17:33:11303struct JsonString {
drh5fa5c102015-08-12 16:49:40304 sqlite3_context *pCtx; /* Function context - put error messages here */
drh5634cc02015-08-17 11:28:03305 char *zBuf; /* Append JSON content here */
drh5fa5c102015-08-12 16:49:40306 u64 nAlloc; /* Bytes of storage available in zBuf[] */
307 u64 nUsed; /* Bytes of zBuf[] currently used */
308 u8 bStatic; /* True if zBuf is static space */
drhe1e2f2d2023-10-06 14:52:49309 u8 eErr; /* True if an error has been encountered */
drh5fa5c102015-08-12 16:49:40310 char zSpace[100]; /* Initial static space */
311};
312
drhe1e2f2d2023-10-06 14:52:49313/* Allowed values for JsonString.eErr */
314#define JSTRING_OOM 0x01 /* Out of memory */
315#define JSTRING_MALFORMED 0x02 /* Malformed JSONB */
316#define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */
317
drhae5f55e2023-09-29 12:45:14318/* The "subtype" set for text JSON values passed through using
319** sqlite3_result_subtype() and sqlite3_value_subtype().
320*/
321#define JSON_SUBTYPE 74 /* Ascii for "J" */
322
drh42156fd2023-09-26 19:30:46323/*
drha0de4542023-12-05 18:28:15324** Bit values for the flags passed into various SQL function implementations
325** via the sqlite3_user_data() value.
drh42156fd2023-09-26 19:30:46326*/
327#define JSON_JSON 0x01 /* Result is always JSON */
328#define JSON_SQL 0x02 /* Result is always SQL */
329#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */
330#define JSON_ISSET 0x04 /* json_set(), not json_insert() */
331#define JSON_BLOB 0x08 /* Use the BLOB output format */
332
drh987eb1f2015-08-17 15:17:37333
drh4b9ed1b2023-11-30 23:36:14334/* A parsed JSON value. Lifecycle:
drh7286c592023-07-26 13:17:43335**
drh4b9ed1b2023-11-30 23:36:14336** 1. JSON comes in and is parsed into a JSONB value in aBlob. The
drhc1e85742023-12-02 20:25:36337** original text is stored in zJson. This step is skipped if the
338** input is JSONB instead of text JSON.
drh77253702023-07-26 11:43:39339**
drhc1e85742023-12-02 20:25:36340** 2. The aBlob[] array is searched using the JSON path notation, if needed.
drh4b9ed1b2023-11-30 23:36:14341**
drhc1e85742023-12-02 20:25:36342** 3. Zero or more changes are made to aBlob[] (via json_remove() or
343** json_replace() or json_patch() or similar).
drh77253702023-07-26 11:43:39344**
drhc1e85742023-12-02 20:25:36345** 4. New JSON text is generated from the aBlob[] for output. This step
drh3262ca82023-12-19 21:39:58346** is skipped if the function is one of the jsonb_* functions that
347** returns JSONB instead of text JSON.
drhe9c37f32015-08-15 21:25:36348*/
drhe9c37f32015-08-15 21:25:36349struct JsonParse {
drh4b9ed1b2023-11-30 23:36:14350 u8 *aBlob; /* JSONB representation of JSON value */
351 u32 nBlob; /* Bytes of aBlob[] actually used */
352 u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */
drhca1ce772023-12-01 12:57:12353 char *zJson; /* Json text used for parsing */
drh4093b292024-01-03 16:41:50354 sqlite3 *db; /* The database connection to which this object belongs */
drh063d0d42023-12-01 18:46:14355 int nJson; /* Length of the zJson string in bytes */
drh3262ca82023-12-19 21:39:58356 u32 nJPRef; /* Number of references to this object */
357 u32 iErr; /* Error location in zJson[] */
drhff6d50e2017-04-11 18:55:05358 u16 iDepth; /* Nesting depth */
drh058f3db2023-04-25 21:24:20359 u8 nErr; /* Number of errors seen */
360 u8 oom; /* Set to true if out of memory */
drh063d0d42023-12-01 18:46:14361 u8 bJsonIsRCStr; /* True if zJson is an RCStr */
drh7be14732023-04-30 19:34:41362 u8 hasNonstd; /* True if input uses non-standard features like JSON5 */
drh063d0d42023-12-01 18:46:14363 u8 bReadOnly; /* Do not modify. */
drh53c21602023-12-02 18:17:38364 /* Search and edit information. See jsonLookupStep() */
drh7b5123c2023-11-03 12:09:22365 u8 eEdit; /* Edit operation to apply */
366 int delta; /* Size change due to the edit */
367 u32 nIns; /* Number of bytes to insert */
drhb7d5cb72023-11-25 13:40:19368 u32 iLabel; /* Location of label if search landed on an object value */
drh7b5123c2023-11-03 12:09:22369 u8 *aIns; /* Content to be inserted */
drhe9c37f32015-08-15 21:25:36370};
371
drh7b5123c2023-11-03 12:09:22372/* Allowed values for JsonParse.eEdit */
drh27fea972023-11-21 20:13:08373#define JEDIT_DEL 1 /* Delete if exists */
374#define JEDIT_REPL 2 /* Overwrite if exists */
375#define JEDIT_INS 3 /* Insert if not exists */
376#define JEDIT_SET 4 /* Insert or overwrite */
drh7b5123c2023-11-03 12:09:22377
drhff6d50e2017-04-11 18:55:05378/*
379** Maximum nesting depth of JSON for this implementation.
380**
381** This limit is needed to avoid a stack overflow in the recursive
drh4e738632023-05-05 20:22:06382** descent parser. A depth of 1000 is far deeper than any sane JSON
383** should go. Historical note: This limit was 2000 prior to version 3.42.0
drhff6d50e2017-04-11 18:55:05384*/
drha0de4542023-12-05 18:28:15385#ifndef SQLITE_JSON_MAX_DEPTH
386# define JSON_MAX_DEPTH 1000
387#else
388# define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH
389#endif
drhff6d50e2017-04-11 18:55:05390
drhbfc7e622023-11-30 00:52:33391/*
392** Allowed values for the flgs argument to jsonParseFuncArg();
393*/
394#define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */
drh38aeb972023-11-30 20:57:48395#define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */
drhbfc7e622023-11-30 00:52:33396
drh505ad2c2015-08-21 17:33:11397/**************************************************************************
drh5624b0b2023-10-02 12:40:04398** Forward references
399**************************************************************************/
400static void jsonReturnStringAsBlob(JsonString*);
drhcbe4a262025-04-21 19:53:12401static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p);
drh3262ca82023-12-19 21:39:58402static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*);
drhbfc7e622023-11-30 00:52:33403static void jsonReturnParse(sqlite3_context*,JsonParse*);
404static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32);
drh063d0d42023-12-01 18:46:14405static void jsonParseFree(JsonParse*);
drh7d2eaae2023-12-11 17:03:12406static u32 jsonbPayloadSize(const JsonParse*, u32, u32*);
drhcc1a39f2023-12-12 02:31:12407static u32 jsonUnescapeOneChar(const char*, u32, u32*);
drh063d0d42023-12-01 18:46:14408
drhca1ce772023-12-01 12:57:12409/**************************************************************************
410** Utility routines for dealing with JsonCache objects
411**************************************************************************/
412
413/*
414** Free a JsonCache object.
415*/
416static void jsonCacheDelete(JsonCache *p){
417 int i;
418 for(i=0; i<p->nUsed; i++){
drh063d0d42023-12-01 18:46:14419 jsonParseFree(p->a[i]);
drhca1ce772023-12-01 12:57:12420 }
421 sqlite3DbFree(p->db, p);
422}
423static void jsonCacheDeleteGeneric(void *p){
424 jsonCacheDelete((JsonCache*)p);
425}
426
427/*
drhc1e85742023-12-02 20:25:36428** Insert a new entry into the cache. If the cache is full, expel
drhca1ce772023-12-01 12:57:12429** the least recently used entry. Return SQLITE_OK on success or a
430** result code otherwise.
431**
drhc1e85742023-12-02 20:25:36432** Cache entries are stored in age order, oldest first.
drhca1ce772023-12-01 12:57:12433*/
434static int jsonCacheInsert(
435 sqlite3_context *ctx, /* The SQL statement context holding the cache */
drh063d0d42023-12-01 18:46:14436 JsonParse *pParse /* The parse object to be added to the cache */
drhca1ce772023-12-01 12:57:12437){
438 JsonCache *p;
drhca1ce772023-12-01 12:57:12439
drh063d0d42023-12-01 18:46:14440 assert( pParse->zJson!=0 );
441 assert( pParse->bJsonIsRCStr );
drh095f2c52023-12-18 15:53:48442 assert( pParse->delta==0 );
drhca1ce772023-12-01 12:57:12443 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
444 if( p==0 ){
445 sqlite3 *db = sqlite3_context_db_handle(ctx);
446 p = sqlite3DbMallocZero(db, sizeof(*p));
447 if( p==0 ) return SQLITE_NOMEM;
448 p->db = db;
449 sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric);
450 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
451 if( p==0 ) return SQLITE_NOMEM;
452 }
drhca1ce772023-12-01 12:57:12453 if( p->nUsed >= JSON_CACHE_SIZE ){
drh063d0d42023-12-01 18:46:14454 jsonParseFree(p->a[0]);
drhca1ce772023-12-01 12:57:12455 memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0]));
456 p->nUsed = JSON_CACHE_SIZE-1;
457 }
drha11aaff2023-12-02 18:04:27458 assert( pParse->nBlobAlloc>0 );
drh063d0d42023-12-01 18:46:14459 pParse->eEdit = 0;
460 pParse->nJPRef++;
461 pParse->bReadOnly = 1;
462 p->a[p->nUsed] = pParse;
drhca1ce772023-12-01 12:57:12463 p->nUsed++;
464 return SQLITE_OK;
465}
466
467/*
drh063d0d42023-12-01 18:46:14468** Search for a cached translation the json text supplied by pArg. Return
drhc1e85742023-12-02 20:25:36469** the JsonParse object if found. Return NULL if not found.
470**
471** When a match if found, the matching entry is moved to become the
472** most-recently used entry if it isn't so already.
473**
474** The JsonParse object returned still belongs to the Cache and might
stephanda5f8132025-02-27 21:17:55475** be deleted at any moment. If the caller wants the JsonParse to
drhc1e85742023-12-02 20:25:36476** linger, it needs to increment the nPJRef reference counter.
drhca1ce772023-12-01 12:57:12477*/
drh063d0d42023-12-01 18:46:14478static JsonParse *jsonCacheSearch(
drhca1ce772023-12-01 12:57:12479 sqlite3_context *ctx, /* The SQL statement context holding the cache */
drh063d0d42023-12-01 18:46:14480 sqlite3_value *pArg /* Function argument containing SQL text */
drhca1ce772023-12-01 12:57:12481){
482 JsonCache *p;
483 int i;
drh063d0d42023-12-01 18:46:14484 const char *zJson;
485 int nJson;
drhca1ce772023-12-01 12:57:12486
drh063d0d42023-12-01 18:46:14487 if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){
488 return 0;
489 }
490 zJson = (const char*)sqlite3_value_text(pArg);
491 if( zJson==0 ) return 0;
492 nJson = sqlite3_value_bytes(pArg);
493
drhca1ce772023-12-01 12:57:12494 p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID);
495 if( p==0 ){
drhca1ce772023-12-01 12:57:12496 return 0;
497 }
498 for(i=0; i<p->nUsed; i++){
drh063d0d42023-12-01 18:46:14499 if( p->a[i]->zJson==zJson ) break;
drhca1ce772023-12-01 12:57:12500 }
501 if( i>=p->nUsed ){
502 for(i=0; i<p->nUsed; i++){
drh063d0d42023-12-01 18:46:14503 if( p->a[i]->nJson!=nJson ) continue;
504 if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break;
drhca1ce772023-12-01 12:57:12505 }
506 }
507 if( i<p->nUsed ){
508 if( i<p->nUsed-1 ){
drhc1e85742023-12-02 20:25:36509 /* Make the matching entry the most recently used entry */
drh063d0d42023-12-01 18:46:14510 JsonParse *tmp = p->a[i];
drhca1ce772023-12-01 12:57:12511 memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp));
512 p->a[p->nUsed-1] = tmp;
drh5bfa7e62023-12-01 13:28:13513 i = p->nUsed - 1;
drhca1ce772023-12-01 12:57:12514 }
drh095f2c52023-12-18 15:53:48515 assert( p->a[i]->delta==0 );
drh063d0d42023-12-01 18:46:14516 return p->a[i];
drhca1ce772023-12-01 12:57:12517 }else{
drhca1ce772023-12-01 12:57:12518 return 0;
519 }
520}
drh5624b0b2023-10-02 12:40:04521
522/**************************************************************************
drh505ad2c2015-08-21 17:33:11523** Utility routines for dealing with JsonString objects
524**************************************************************************/
drh301eecc2015-08-17 20:14:19525
drhae5f55e2023-09-29 12:45:14526/* Turn uninitialized bulk memory into a valid JsonString object
527** holding a zero-length string.
drh5fa5c102015-08-12 16:49:40528*/
drhae5f55e2023-09-29 12:45:14529static void jsonStringZero(JsonString *p){
drh5fa5c102015-08-12 16:49:40530 p->zBuf = p->zSpace;
531 p->nAlloc = sizeof(p->zSpace);
532 p->nUsed = 0;
533 p->bStatic = 1;
534}
535
drh505ad2c2015-08-21 17:33:11536/* Initialize the JsonString object
drh5fa5c102015-08-12 16:49:40537*/
drhae5f55e2023-09-29 12:45:14538static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){
drh5fa5c102015-08-12 16:49:40539 p->pCtx = pCtx;
drhe1e2f2d2023-10-06 14:52:49540 p->eErr = 0;
drhae5f55e2023-09-29 12:45:14541 jsonStringZero(p);
drh5fa5c102015-08-12 16:49:40542}
543
drh505ad2c2015-08-21 17:33:11544/* Free all allocated memory and reset the JsonString object back to its
drh5fa5c102015-08-12 16:49:40545** initial state.
546*/
drhae5f55e2023-09-29 12:45:14547static void jsonStringReset(JsonString *p){
drhf02cc9a2023-07-25 15:08:18548 if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf);
drhae5f55e2023-09-29 12:45:14549 jsonStringZero(p);
drh5fa5c102015-08-12 16:49:40550}
551
drh77253702023-07-26 11:43:39552/* Report an out-of-memory (OOM) condition
drh5fa5c102015-08-12 16:49:40553*/
drhae5f55e2023-09-29 12:45:14554static void jsonStringOom(JsonString *p){
drhe1e2f2d2023-10-06 14:52:49555 p->eErr |= JSTRING_OOM;
drh15c0b032023-11-26 00:56:40556 if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx);
drhae5f55e2023-09-29 12:45:14557 jsonStringReset(p);
drh5fa5c102015-08-12 16:49:40558}
559
560/* Enlarge pJson->zBuf so that it can hold at least N more bytes.
561** Return zero on success. Return non-zero on an OOM error
562*/
drhae5f55e2023-09-29 12:45:14563static int jsonStringGrow(JsonString *p, u32 N){
drh301eecc2015-08-17 20:14:19564 u64 nTotal = N<p->nAlloc ? p->nAlloc*2 : p->nAlloc+N+10;
drh5fa5c102015-08-12 16:49:40565 char *zNew;
566 if( p->bStatic ){
drhe1e2f2d2023-10-06 14:52:49567 if( p->eErr ) return 1;
drhf02cc9a2023-07-25 15:08:18568 zNew = sqlite3RCStrNew(nTotal);
drh5fa5c102015-08-12 16:49:40569 if( zNew==0 ){
drhae5f55e2023-09-29 12:45:14570 jsonStringOom(p);
drh5fa5c102015-08-12 16:49:40571 return SQLITE_NOMEM;
572 }
drh6fd5c1e2015-08-21 20:37:12573 memcpy(zNew, p->zBuf, (size_t)p->nUsed);
drh5fa5c102015-08-12 16:49:40574 p->zBuf = zNew;
575 p->bStatic = 0;
576 }else{
drhf02cc9a2023-07-25 15:08:18577 p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal);
578 if( p->zBuf==0 ){
drhe1e2f2d2023-10-06 14:52:49579 p->eErr |= JSTRING_OOM;
drhae5f55e2023-09-29 12:45:14580 jsonStringZero(p);
drh5fa5c102015-08-12 16:49:40581 return SQLITE_NOMEM;
582 }
drh5fa5c102015-08-12 16:49:40583 }
584 p->nAlloc = nTotal;
585 return SQLITE_OK;
586}
587
drh505ad2c2015-08-21 17:33:11588/* Append N bytes from zIn onto the end of the JsonString string.
drh5fa5c102015-08-12 16:49:40589*/
drhae5f55e2023-09-29 12:45:14590static SQLITE_NOINLINE void jsonStringExpandAndAppend(
drh8376ae72023-07-19 15:06:29591 JsonString *p,
592 const char *zIn,
593 u32 N
594){
595 assert( N>0 );
drhae5f55e2023-09-29 12:45:14596 if( jsonStringGrow(p,N) ) return;
drh5fa5c102015-08-12 16:49:40597 memcpy(p->zBuf+p->nUsed, zIn, N);
598 p->nUsed += N;
599}
drh8376ae72023-07-19 15:06:29600static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
601 if( N==0 ) return;
602 if( N+p->nUsed >= p->nAlloc ){
drhae5f55e2023-09-29 12:45:14603 jsonStringExpandAndAppend(p,zIn,N);
drh8376ae72023-07-19 15:06:29604 }else{
605 memcpy(p->zBuf+p->nUsed, zIn, N);
606 p->nUsed += N;
607 }
608}
609static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
drheb18ae32023-12-03 00:51:30610 assert( N>0 );
drh8376ae72023-07-19 15:06:29611 if( N+p->nUsed >= p->nAlloc ){
drhae5f55e2023-09-29 12:45:14612 jsonStringExpandAndAppend(p,zIn,N);
drh8376ae72023-07-19 15:06:29613 }else{
614 memcpy(p->zBuf+p->nUsed, zIn, N);
615 p->nUsed += N;
616 }
617}
618
drh4af352d2015-08-21 20:02:48619/* Append formatted text (not to exceed N bytes) to the JsonString.
620*/
621static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
622 va_list ap;
drhae5f55e2023-09-29 12:45:14623 if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return;
drh4af352d2015-08-21 20:02:48624 va_start(ap, zFormat);
625 sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap);
626 va_end(ap);
627 p->nUsed += (int)strlen(p->zBuf+p->nUsed);
628}
629
drh5634cc02015-08-17 11:28:03630/* Append a single character
631*/
drh8376ae72023-07-19 15:06:29632static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){
drhae5f55e2023-09-29 12:45:14633 if( jsonStringGrow(p,1) ) return;
drh5634cc02015-08-17 11:28:03634 p->zBuf[p->nUsed++] = c;
635}
drh8376ae72023-07-19 15:06:29636static void jsonAppendChar(JsonString *p, char c){
637 if( p->nUsed>=p->nAlloc ){
638 jsonAppendCharExpand(p,c);
639 }else{
640 p->zBuf[p->nUsed++] = c;
641 }
642}
drh5634cc02015-08-17 11:28:03643
drh777a0882024-01-20 12:13:00644/* Remove a single character from the end of the string
645*/
646static void jsonStringTrimOneChar(JsonString *p){
647 if( p->eErr==0 ){
648 assert( p->nUsed>0 );
649 p->nUsed--;
650 }
651}
652
653
drh86db4552023-10-11 13:19:37654/* Make sure there is a zero terminator on p->zBuf[]
drh9a184da2023-07-26 11:00:47655**
656** Return true on success. Return false if an OOM prevents this
657** from happening.
658*/
drhdc138cb2023-12-04 13:12:45659static int jsonStringTerminate(JsonString *p){
drh9a184da2023-07-26 11:00:47660 jsonAppendChar(p, 0);
drh777a0882024-01-20 12:13:00661 jsonStringTrimOneChar(p);
drhdc138cb2023-12-04 13:12:45662 return p->eErr==0;
drh9a184da2023-07-26 11:00:47663}
664
drh301eecc2015-08-17 20:14:19665/* Append a comma separator to the output buffer, if the previous
666** character is not '[' or '{'.
667*/
drh505ad2c2015-08-21 17:33:11668static void jsonAppendSeparator(JsonString *p){
drh301eecc2015-08-17 20:14:19669 char c;
670 if( p->nUsed==0 ) return;
671 c = p->zBuf[p->nUsed-1];
drh8376ae72023-07-19 15:06:29672 if( c=='[' || c=='{' ) return;
673 jsonAppendChar(p, ',');
drh301eecc2015-08-17 20:14:19674}
675
drhc24f5362024-01-31 13:46:44676/* c is a control character. Append the canonical JSON representation
677** of that control character to p.
678**
679** This routine assumes that the output buffer has already been enlarged
680** sufficiently to hold the worst-case encoding plus a nul terminator.
681*/
682static void jsonAppendControlChar(JsonString *p, u8 c){
683 static const char aSpecial[] = {
684 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
685 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
686 };
687 assert( sizeof(aSpecial)==32 );
688 assert( aSpecial['\b']=='b' );
689 assert( aSpecial['\f']=='f' );
690 assert( aSpecial['\n']=='n' );
691 assert( aSpecial['\r']=='r' );
692 assert( aSpecial['\t']=='t' );
693 assert( c>=0 && c<sizeof(aSpecial) );
694 assert( p->nUsed+7 <= p->nAlloc );
695 if( aSpecial[c] ){
696 p->zBuf[p->nUsed] = '\\';
697 p->zBuf[p->nUsed+1] = aSpecial[c];
698 p->nUsed += 2;
699 }else{
700 p->zBuf[p->nUsed] = '\\';
701 p->zBuf[p->nUsed+1] = 'u';
702 p->zBuf[p->nUsed+2] = '0';
703 p->zBuf[p->nUsed+3] = '0';
704 p->zBuf[p->nUsed+4] = "0123456789abcdef"[c>>4];
705 p->zBuf[p->nUsed+5] = "0123456789abcdef"[c&0xf];
706 p->nUsed += 6;
707 }
708}
709
drh505ad2c2015-08-21 17:33:11710/* Append the N-byte string in zIn to the end of the JsonString string
drhc1e85742023-12-02 20:25:36711** under construction. Enclose the string in double-quotes ("...") and
712** escape any double-quotes or backslash characters contained within the
drh5fa5c102015-08-12 16:49:40713** string.
drhc1e85742023-12-02 20:25:36714**
715** This routine is a high-runner. There is a measurable performance
716** increase associated with unwinding the jsonIsOk[] loop.
drh5fa5c102015-08-12 16:49:40717*/
drh505ad2c2015-08-21 17:33:11718static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
drhf0b8b162023-12-02 14:16:47719 u32 k;
720 u8 c;
721 const u8 *z = (const u8*)zIn;
722 if( z==0 ) return;
drhae5f55e2023-09-29 12:45:14723 if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return;
drh5fa5c102015-08-12 16:49:40724 p->zBuf[p->nUsed++] = '"';
drhf0b8b162023-12-02 14:16:47725 while( 1 /*exit-by-break*/ ){
726 k = 0;
drh4c13d3c2023-12-28 19:18:08727 /* The following while() is the 4-way unwound equivalent of
728 **
729 ** while( k<N && jsonIsOk[z[k]] ){ k++; }
730 */
731 while( 1 /* Exit by break */ ){
732 if( k+3>=N ){
733 while( k<N && jsonIsOk[z[k]] ){ k++; }
734 break;
735 }
736 if( !jsonIsOk[z[k]] ){
737 break;
738 }
739 if( !jsonIsOk[z[k+1]] ){
740 k += 1;
741 break;
742 }
743 if( !jsonIsOk[z[k+2]] ){
744 k += 2;
745 break;
746 }
747 if( !jsonIsOk[z[k+3]] ){
748 k += 3;
749 break;
750 }else{
751 k += 4;
752 }
753 }
drhf0b8b162023-12-02 14:16:47754 if( k>=N ){
755 if( k>0 ){
756 memcpy(&p->zBuf[p->nUsed], z, k);
757 p->nUsed += k;
758 }
759 break;
760 }
761 if( k>0 ){
762 memcpy(&p->zBuf[p->nUsed], z, k);
763 p->nUsed += k;
764 z += k;
765 N -= k;
766 }
767 c = z[0];
768 if( c=='"' || c=='\\' ){
drhf0b8b162023-12-02 14:16:47769 if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return;
drh5fa5c102015-08-12 16:49:40770 p->zBuf[p->nUsed++] = '\\';
drhc874d602023-08-02 16:06:02771 p->zBuf[p->nUsed++] = c;
772 }else if( c=='\'' ){
773 p->zBuf[p->nUsed++] = c;
774 }else{
drhf0b8b162023-12-02 14:16:47775 if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return;
drhc24f5362024-01-31 13:46:44776 jsonAppendControlChar(p, c);
drh5fa5c102015-08-12 16:49:40777 }
drhf0b8b162023-12-02 14:16:47778 z++;
779 N--;
drh5fa5c102015-08-12 16:49:40780 }
781 p->zBuf[p->nUsed++] = '"';
drh4977ccf2015-09-19 11:57:26782 assert( p->nUsed<p->nAlloc );
drh5fa5c102015-08-12 16:49:40783}
784
drhd0960592015-08-17 21:22:32785/*
drhae5f55e2023-09-29 12:45:14786** Append an sqlite3_value (such as a function parameter) to the JSON
787** string under construction in p.
drhd0960592015-08-17 21:22:32788*/
drhae5f55e2023-09-29 12:45:14789static void jsonAppendSqlValue(
drh505ad2c2015-08-21 17:33:11790 JsonString *p, /* Append to this JSON string */
drhf5ddb9c2015-09-11 00:06:41791 sqlite3_value *pValue /* Value to append */
drhd0960592015-08-17 21:22:32792){
793 switch( sqlite3_value_type(pValue) ){
794 case SQLITE_NULL: {
drh8376ae72023-07-19 15:06:29795 jsonAppendRawNZ(p, "null", 4);
drhd0960592015-08-17 21:22:32796 break;
797 }
drhd0960592015-08-17 21:22:32798 case SQLITE_FLOAT: {
drh667b5cc2023-03-17 20:31:24799 jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue));
800 break;
801 }
802 case SQLITE_INTEGER: {
drhd0960592015-08-17 21:22:32803 const char *z = (const char*)sqlite3_value_text(pValue);
804 u32 n = (u32)sqlite3_value_bytes(pValue);
805 jsonAppendRaw(p, z, n);
806 break;
807 }
808 case SQLITE_TEXT: {
809 const char *z = (const char*)sqlite3_value_text(pValue);
810 u32 n = (u32)sqlite3_value_bytes(pValue);
drhf5ddb9c2015-09-11 00:06:41811 if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){
drhecb5fed2015-08-28 03:33:50812 jsonAppendRaw(p, z, n);
813 }else{
814 jsonAppendString(p, z, n);
815 }
drhd0960592015-08-17 21:22:32816 break;
817 }
818 default: {
drhcbe4a262025-04-21 19:53:12819 JsonParse px;
820 memset(&px, 0, sizeof(px));
821 if( jsonArgIsJsonb(pValue, &px) ){
drh3262ca82023-12-19 21:39:58822 jsonTranslateBlobToText(&px, 0, p);
drhe1e2f2d2023-10-06 14:52:49823 }else if( p->eErr==0 ){
drhd0960592015-08-17 21:22:32824 sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1);
drhe1e2f2d2023-10-06 14:52:49825 p->eErr = JSTRING_ERR;
drhae5f55e2023-09-29 12:45:14826 jsonStringReset(p);
drhd0960592015-08-17 21:22:32827 }
828 break;
829 }
830 }
831}
832
drhae5f55e2023-09-29 12:45:14833/* Make the text in p (which is probably a generated JSON text string)
834** the result of the SQL function.
drhf02cc9a2023-07-25 15:08:18835**
drhae5f55e2023-09-29 12:45:14836** The JsonString is reset.
drhca1ce772023-12-01 12:57:12837**
drh063d0d42023-12-01 18:46:14838** If pParse and ctx are both non-NULL, then the SQL string in p is
839** loaded into the zJson field of the pParse object as a RCStr and the
840** pParse is added to the cache.
drh5fa5c102015-08-12 16:49:40841*/
drhca1ce772023-12-01 12:57:12842static void jsonReturnString(
843 JsonString *p, /* String to return */
844 JsonParse *pParse, /* JSONB source or NULL */
845 sqlite3_context *ctx /* Where to cache */
846){
847 assert( (pParse!=0)==(ctx!=0) );
848 assert( ctx==0 || ctx==p->pCtx );
drhe1e2f2d2023-10-06 14:52:49849 if( p->eErr==0 ){
drh7e86d3f2023-09-30 14:34:39850 int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx));
851 if( flags & JSON_BLOB ){
852 jsonReturnStringAsBlob(p);
853 }else if( p->bStatic ){
drh93853a42023-07-27 00:21:59854 sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
855 SQLITE_TRANSIENT, SQLITE_UTF8);
drhdc138cb2023-12-04 13:12:45856 }else if( jsonStringTerminate(p) ){
drha11aaff2023-12-02 18:04:27857 if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){
drh063d0d42023-12-01 18:46:14858 int rc;
859 pParse->zJson = sqlite3RCStrRef(p->zBuf);
860 pParse->nJson = p->nUsed;
861 pParse->bJsonIsRCStr = 1;
862 rc = jsonCacheInsert(ctx, pParse);
drhca1ce772023-12-01 12:57:12863 if( rc==SQLITE_NOMEM ){
drhca1ce772023-12-01 12:57:12864 sqlite3_result_error_nomem(ctx);
865 jsonStringReset(p);
866 return;
867 }
868 }
drh063d0d42023-12-01 18:46:14869 sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed,
drh43dc31c2023-10-17 19:33:52870 sqlite3RCStrUnref,
drh93853a42023-07-27 00:21:59871 SQLITE_UTF8);
drhe1e2f2d2023-10-06 14:52:49872 }else{
873 sqlite3_result_error_nomem(p->pCtx);
drh93853a42023-07-27 00:21:59874 }
drhe1e2f2d2023-10-06 14:52:49875 }else if( p->eErr & JSTRING_OOM ){
drhf02cc9a2023-07-25 15:08:18876 sqlite3_result_error_nomem(p->pCtx);
drhe1e2f2d2023-10-06 14:52:49877 }else if( p->eErr & JSTRING_MALFORMED ){
878 sqlite3_result_error(p->pCtx, "malformed JSON", -1);
drh5fa5c102015-08-12 16:49:40879 }
drhae5f55e2023-09-29 12:45:14880 jsonStringReset(p);
drh5fa5c102015-08-12 16:49:40881}
882
drh505ad2c2015-08-21 17:33:11883/**************************************************************************
drh4b9ed1b2023-11-30 23:36:14884** Utility routines for dealing with JsonParse objects
drh505ad2c2015-08-21 17:33:11885**************************************************************************/
886
887/*
drh505ad2c2015-08-21 17:33:11888** Reclaim all memory allocated by a JsonParse object. But do not
889** delete the JsonParse object itself.
890*/
891static void jsonParseReset(JsonParse *pParse){
drh51d78692023-07-20 17:45:09892 assert( pParse->nJPRef<=1 );
drh063d0d42023-12-01 18:46:14893 if( pParse->bJsonIsRCStr ){
894 sqlite3RCStrUnref(pParse->zJson);
895 pParse->zJson = 0;
896 pParse->nJson = 0;
897 pParse->bJsonIsRCStr = 0;
drh6bc4baf2023-07-27 20:28:29898 }
drhab702662023-11-24 14:25:56899 if( pParse->nBlobAlloc ){
drh4093b292024-01-03 16:41:50900 sqlite3DbFree(pParse->db, pParse->aBlob);
drhab702662023-11-24 14:25:56901 pParse->aBlob = 0;
902 pParse->nBlob = 0;
903 pParse->nBlobAlloc = 0;
904 }
drh505ad2c2015-08-21 17:33:11905}
906
drh5634cc02015-08-17 11:28:03907/*
drhc1e85742023-12-02 20:25:36908** Decrement the reference count on the JsonParse object. When the
909** count reaches zero, free the object.
drh3fb153c2017-05-11 16:49:59910*/
911static void jsonParseFree(JsonParse *pParse){
drhef97f832023-11-28 18:16:02912 if( pParse ){
913 if( pParse->nJPRef>1 ){
914 pParse->nJPRef--;
915 }else{
916 jsonParseReset(pParse);
drh4093b292024-01-03 16:41:50917 sqlite3DbFree(pParse->db, pParse);
drhef97f832023-11-28 18:16:02918 }
drh51d78692023-07-20 17:45:09919 }
drh3fb153c2017-05-11 16:49:59920}
921
drha0de4542023-12-05 18:28:15922/**************************************************************************
923** Utility routines for the JSON text parser
924**************************************************************************/
925
drh3fb153c2017-05-11 16:49:59926/*
drh78fa0182023-12-03 11:54:39927** Translate a single byte of Hex into an integer.
928** This routine only gives a correct answer if h really is a valid hexadecimal
929** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not
930** assert() if the digit is not hex.
931*/
932static u8 jsonHexToInt(int h){
933#ifdef SQLITE_ASCII
934 h += 9*(1&(h>>6));
935#endif
936#ifdef SQLITE_EBCDIC
937 h += 9*(1&~(h>>4));
938#endif
939 return (u8)(h & 0xf);
940}
941
942/*
drh48eb03b2019-11-10 11:09:06943** Convert a 4-byte hex string into an integer
944*/
945static u32 jsonHexToInt4(const char *z){
946 u32 v;
drh78fa0182023-12-03 11:54:39947 v = (jsonHexToInt(z[0])<<12)
948 + (jsonHexToInt(z[1])<<8)
949 + (jsonHexToInt(z[2])<<4)
950 + jsonHexToInt(z[3]);
drh48eb03b2019-11-10 11:09:06951 return v;
952}
953
954/*
drhc5ee2d82023-04-26 20:26:14955** Return true if z[] begins with 2 (or more) hexadecimal digits
956*/
957static int jsonIs2Hex(const char *z){
958 return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]);
959}
960
961/*
drhad875e72016-11-07 13:37:28962** Return true if z[] begins with 4 (or more) hexadecimal digits
963*/
964static int jsonIs4Hex(const char *z){
drhc5ee2d82023-04-26 20:26:14965 return jsonIs2Hex(z) && jsonIs2Hex(&z[2]);
drhad875e72016-11-07 13:37:28966}
967
drhf62518f2023-04-26 15:19:19968/*
969** Return the number of bytes of JSON5 whitespace at the beginning of
970** the input string z[].
971**
972** JSON5 whitespace consists of any of the following characters:
973**
974** Unicode UTF-8 Name
975** U+0009 09 horizontal tab
976** U+000a 0a line feed
977** U+000b 0b vertical tab
978** U+000c 0c form feed
979** U+000d 0d carriage return
980** U+0020 20 space
981** U+00a0 c2 a0 non-breaking space
982** U+1680 e1 9a 80 ogham space mark
983** U+2000 e2 80 80 en quad
984** U+2001 e2 80 81 em quad
985** U+2002 e2 80 82 en space
986** U+2003 e2 80 83 em space
987** U+2004 e2 80 84 three-per-em space
988** U+2005 e2 80 85 four-per-em space
989** U+2006 e2 80 86 six-per-em space
990** U+2007 e2 80 87 figure space
991** U+2008 e2 80 88 punctuation space
992** U+2009 e2 80 89 thin space
993** U+200a e2 80 8a hair space
994** U+2028 e2 80 a8 line separator
995** U+2029 e2 80 a9 paragraph separator
996** U+202f e2 80 af narrow no-break space (NNBSP)
997** U+205f e2 81 9f medium mathematical space (MMSP)
998** U+3000 e3 80 80 ideographical space
999** U+FEFF ef bb bf byte order mark
1000**
1001** In addition, comments between '/', '*' and '*', '/' and
1002** from '/', '/' to end-of-line are also considered to be whitespace.
1003*/
1004static int json5Whitespace(const char *zIn){
1005 int n = 0;
1006 const u8 *z = (u8*)zIn;
1007 while( 1 /*exit by "goto whitespace_done"*/ ){
1008 switch( z[n] ){
1009 case 0x09:
1010 case 0x0a:
1011 case 0x0b:
1012 case 0x0c:
1013 case 0x0d:
1014 case 0x20: {
1015 n++;
1016 break;
1017 }
1018 case '/': {
1019 if( z[n+1]=='*' && z[n+2]!=0 ){
1020 int j;
1021 for(j=n+3; z[j]!='/' || z[j-1]!='*'; j++){
1022 if( z[j]==0 ) goto whitespace_done;
1023 }
drh8f3fe2e2023-04-28 23:38:541024 n = j+1;
drhf62518f2023-04-26 15:19:191025 break;
1026 }else if( z[n+1]=='/' ){
1027 int j;
drh8f3fe2e2023-04-28 23:38:541028 char c;
1029 for(j=n+2; (c = z[j])!=0; j++){
1030 if( c=='\n' || c=='\r' ) break;
1031 if( 0xe2==(u8)c && 0x80==(u8)z[j+1]
1032 && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])
1033 ){
1034 j += 2;
1035 break;
1036 }
1037 }
1038 n = j;
1039 if( z[n] ) n++;
drhf62518f2023-04-26 15:19:191040 break;
1041 }
1042 goto whitespace_done;
1043 }
1044 case 0xc2: {
1045 if( z[n+1]==0xa0 ){
1046 n += 2;
1047 break;
1048 }
1049 goto whitespace_done;
1050 }
1051 case 0xe1: {
1052 if( z[n+1]==0x9a && z[n+2]==0x80 ){
1053 n += 3;
1054 break;
1055 }
1056 goto whitespace_done;
1057 }
1058 case 0xe2: {
1059 if( z[n+1]==0x80 ){
1060 u8 c = z[n+2];
1061 if( c<0x80 ) goto whitespace_done;
1062 if( c<=0x8a || c==0xa8 || c==0xa9 || c==0xaf ){
1063 n += 3;
1064 break;
1065 }
1066 }else if( z[n+1]==0x81 && z[n+2]==0x9f ){
1067 n += 3;
1068 break;
1069 }
1070 goto whitespace_done;
1071 }
1072 case 0xe3: {
1073 if( z[n+1]==0x80 && z[n+2]==0x80 ){
1074 n += 3;
1075 break;
1076 }
1077 goto whitespace_done;
1078 }
1079 case 0xef: {
1080 if( z[n+1]==0xbb && z[n+2]==0xbf ){
1081 n += 3;
1082 break;
1083 }
1084 goto whitespace_done;
1085 }
1086 default: {
1087 goto whitespace_done;
1088 }
1089 }
1090 }
1091 whitespace_done:
1092 return n;
1093}
1094
drh8d1005a2023-04-01 23:29:591095/*
1096** Extra floating-point literals to allow in JSON.
1097*/
1098static const struct NanInfName {
1099 char c1;
1100 char c2;
1101 char n;
1102 char eType;
1103 char nRepl;
1104 char *zMatch;
1105 char *zRepl;
1106} aNanInfName[] = {
drh4b9ed1b2023-11-30 23:36:141107 { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" },
1108 { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" },
1109 { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" },
1110 { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" },
1111 { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" },
drhdae7ae32023-04-30 20:37:491112};
drh8d1005a2023-04-01 23:29:591113
drh769a8de2023-09-21 18:16:351114
1115/*
drh769a8de2023-09-21 18:16:351116** Report the wrong number of arguments for json_insert(), json_replace()
1117** or json_set().
1118*/
1119static void jsonWrongNumArgs(
1120 sqlite3_context *pCtx,
1121 const char *zFuncName
1122){
1123 char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments",
1124 zFuncName);
1125 sqlite3_result_error(pCtx, zMsg, -1);
1126 sqlite3_free(zMsg);
1127}
1128
drh769a8de2023-09-21 18:16:351129/****************************************************************************
1130** Utility routines for dealing with the binary BLOB representation of JSON
1131****************************************************************************/
1132
drh769a8de2023-09-21 18:16:351133/*
drh6831cad2023-09-21 17:51:391134** Expand pParse->aBlob so that it holds at least N bytes.
1135**
1136** Return the number of errors.
1137*/
1138static int jsonBlobExpand(JsonParse *pParse, u32 N){
1139 u8 *aNew;
drh7bfa4452025-02-17 18:09:241140 u64 t;
drhdac27072023-10-05 20:17:011141 assert( N>pParse->nBlobAlloc );
drh6831cad2023-09-21 17:51:391142 if( pParse->nBlobAlloc==0 ){
1143 t = 100;
1144 }else{
1145 t = pParse->nBlobAlloc*2;
1146 }
1147 if( t<N ) t = N+100;
drh4093b292024-01-03 16:41:501148 aNew = sqlite3DbRealloc(pParse->db, pParse->aBlob, t);
drh6831cad2023-09-21 17:51:391149 if( aNew==0 ){ pParse->oom = 1; return 1; }
drh7bfa4452025-02-17 18:09:241150 assert( t<0x7fffffff );
drh6831cad2023-09-21 17:51:391151 pParse->aBlob = aNew;
drh7bfa4452025-02-17 18:09:241152 pParse->nBlobAlloc = (u32)t;
drh6831cad2023-09-21 17:51:391153 return 0;
1154}
1155
drh7b5123c2023-11-03 12:09:221156/*
1157** If pParse->aBlob is not previously editable (because it is taken
1158** from sqlite3_value_blob(), as indicated by the fact that
1159** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable
1160** by making a copy into space obtained from malloc.
1161**
1162** Return true on success. Return false on OOM.
1163*/
drh27fea972023-11-21 20:13:081164static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){
drh7b5123c2023-11-03 12:09:221165 u8 *aOld;
1166 u32 nSize;
drh063d0d42023-12-01 18:46:141167 assert( !pParse->bReadOnly );
drh2c26bde2023-12-02 15:59:481168 if( pParse->oom ) return 0;
drh7b5123c2023-11-03 12:09:221169 if( pParse->nBlobAlloc>0 ) return 1;
1170 aOld = pParse->aBlob;
drh5026ddb2023-11-28 12:28:281171 nSize = pParse->nBlob + nExtra;
drh7b5123c2023-11-03 12:09:221172 pParse->aBlob = 0;
1173 if( jsonBlobExpand(pParse, nSize) ){
1174 return 0;
1175 }
drh5026ddb2023-11-28 12:28:281176 assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra );
drh7b5123c2023-11-03 12:09:221177 memcpy(pParse->aBlob, aOld, pParse->nBlob);
1178 return 1;
1179}
1180
drhdc138cb2023-12-04 13:12:451181/* Expand pParse->aBlob and append one bytes.
drh6831cad2023-09-21 17:51:391182*/
drhdc138cb2023-12-04 13:12:451183static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte(
drh6831cad2023-09-21 17:51:391184 JsonParse *pParse,
drhdc138cb2023-12-04 13:12:451185 u8 c
drh6831cad2023-09-21 17:51:391186){
drhdc138cb2023-12-04 13:12:451187 jsonBlobExpand(pParse, pParse->nBlob+1);
1188 if( pParse->oom==0 ){
1189 assert( pParse->nBlob+1<=pParse->nBlobAlloc );
1190 pParse->aBlob[pParse->nBlob++] = c;
1191 }
drh6831cad2023-09-21 17:51:391192}
1193
drhdc138cb2023-12-04 13:12:451194/* Append a single character.
drh6831cad2023-09-21 17:51:391195*/
drhdc138cb2023-12-04 13:12:451196static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){
drh6831cad2023-09-21 17:51:391197 if( pParse->nBlob >= pParse->nBlobAlloc ){
drhdc138cb2023-12-04 13:12:451198 jsonBlobExpandAndAppendOneByte(pParse, c);
1199 }else{
1200 pParse->aBlob[pParse->nBlob++] = c;
drh6831cad2023-09-21 17:51:391201 }
drh6831cad2023-09-21 17:51:391202}
1203
drh679c9082023-12-02 13:36:521204/* Slow version of jsonBlobAppendNode() that first resizes the
1205** pParse->aBlob structure.
drh6831cad2023-09-21 17:51:391206*/
drh679c9082023-12-02 13:36:521207static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*);
1208static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode(
drh5ec9c912023-12-02 01:06:331209 JsonParse *pParse,
1210 u8 eType,
drh679c9082023-12-02 13:36:521211 u32 szPayload,
1212 const void *aPayload
drh5ec9c912023-12-02 01:06:331213){
1214 if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return;
drh679c9082023-12-02 13:36:521215 jsonBlobAppendNode(pParse, eType, szPayload, aPayload);
drh5ec9c912023-12-02 01:06:331216}
1217
1218
drh3a7042e2025-04-01 15:17:011219/* Append a node type byte together with the payload size and
drh679c9082023-12-02 13:36:521220** possibly also the payload.
1221**
1222** If aPayload is not NULL, then it is a pointer to the payload which
1223** is also appended. If aPayload is NULL, the pParse->aBlob[] array
1224** is resized (if necessary) so that it is big enough to hold the
1225** payload, but the payload is not appended and pParse->nBlob is left
1226** pointing to where the first byte of payload will eventually be.
drh6831cad2023-09-21 17:51:391227*/
drh679c9082023-12-02 13:36:521228static void jsonBlobAppendNode(
1229 JsonParse *pParse, /* The JsonParse object under construction */
1230 u8 eType, /* Node type. One of JSONB_* */
1231 u32 szPayload, /* Number of bytes of payload */
1232 const void *aPayload /* The payload. Might be NULL */
drh8c559452023-09-22 11:20:351233){
drh5ec9c912023-12-02 01:06:331234 u8 *a;
1235 if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){
drh679c9082023-12-02 13:36:521236 jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload);
drh5ec9c912023-12-02 01:06:331237 return;
1238 }
drh5afd67b2023-12-05 19:24:071239 assert( pParse->aBlob!=0 );
drh5ec9c912023-12-02 01:06:331240 a = &pParse->aBlob[pParse->nBlob];
drh8c559452023-09-22 11:20:351241 if( szPayload<=11 ){
drh5ec9c912023-12-02 01:06:331242 a[0] = eType | (szPayload<<4);
1243 pParse->nBlob += 1;
drh8c559452023-09-22 11:20:351244 }else if( szPayload<=0xff ){
1245 a[0] = eType | 0xc0;
1246 a[1] = szPayload & 0xff;
drh5ec9c912023-12-02 01:06:331247 pParse->nBlob += 2;
drh8c559452023-09-22 11:20:351248 }else if( szPayload<=0xffff ){
1249 a[0] = eType | 0xd0;
1250 a[1] = (szPayload >> 8) & 0xff;
1251 a[2] = szPayload & 0xff;
drh5ec9c912023-12-02 01:06:331252 pParse->nBlob += 3;
drh8c559452023-09-22 11:20:351253 }else{
1254 a[0] = eType | 0xe0;
1255 a[1] = (szPayload >> 24) & 0xff;
1256 a[2] = (szPayload >> 16) & 0xff;
1257 a[3] = (szPayload >> 8) & 0xff;
1258 a[4] = szPayload & 0xff;
drh5ec9c912023-12-02 01:06:331259 pParse->nBlob += 5;
drh8c559452023-09-22 11:20:351260 }
drh679c9082023-12-02 13:36:521261 if( aPayload ){
1262 pParse->nBlob += szPayload;
1263 memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload);
1264 }
drh8c559452023-09-22 11:20:351265}
1266
1267/* Change the payload size for the node at index i to be szPayload.
1268*/
drhef97f832023-11-28 18:16:021269static int jsonBlobChangePayloadSize(
drh8c559452023-09-22 11:20:351270 JsonParse *pParse,
1271 u32 i,
1272 u32 szPayload
1273){
drh6e737b92023-10-03 19:37:191274 u8 *a;
1275 u8 szType;
drhf26833d2023-10-07 19:05:101276 u8 nExtra;
1277 u8 nNeeded;
drhef97f832023-11-28 18:16:021278 int delta;
1279 if( pParse->oom ) return 0;
drh6e737b92023-10-03 19:37:191280 a = &pParse->aBlob[i];
1281 szType = a[0]>>4;
drh8c559452023-09-22 11:20:351282 if( szType<=11 ){
drhf26833d2023-10-07 19:05:101283 nExtra = 0;
1284 }else if( szType==12 ){
1285 nExtra = 1;
1286 }else if( szType==13 ){
1287 nExtra = 2;
drh2bd9f692025-06-02 23:34:421288 }else if( szType==14 ){
drhf26833d2023-10-07 19:05:101289 nExtra = 4;
drh2bd9f692025-06-02 23:34:421290 }else{
1291 nExtra = 8;
drhf26833d2023-10-07 19:05:101292 }
1293 if( szPayload<=11 ){
1294 nNeeded = 0;
1295 }else if( szPayload<=0xff ){
1296 nNeeded = 1;
1297 }else if( szPayload<=0xffff ){
1298 nNeeded = 2;
1299 }else{
1300 nNeeded = 4;
1301 }
1302 delta = nNeeded - nExtra;
1303 if( delta ){
1304 u32 newSize = pParse->nBlob + delta;
1305 if( delta>0 ){
1306 if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){
drhef97f832023-11-28 18:16:021307 return 0; /* OOM error. Error state recorded in pParse->oom. */
drhf26833d2023-10-07 19:05:101308 }
1309 a = &pParse->aBlob[i];
1310 memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1));
1311 }else{
1312 memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta));
1313 }
1314 pParse->nBlob = newSize;
1315 }
1316 if( nNeeded==0 ){
drh8c559452023-09-22 11:20:351317 a[0] = (a[0] & 0x0f) | (szPayload<<4);
drhf26833d2023-10-07 19:05:101318 }else if( nNeeded==1 ){
1319 a[0] = (a[0] & 0x0f) | 0xc0;
drh8c559452023-09-22 11:20:351320 a[1] = szPayload & 0xff;
drhf26833d2023-10-07 19:05:101321 }else if( nNeeded==2 ){
1322 a[0] = (a[0] & 0x0f) | 0xd0;
drh8c559452023-09-22 11:20:351323 a[1] = (szPayload >> 8) & 0xff;
1324 a[2] = szPayload & 0xff;
1325 }else{
drhf26833d2023-10-07 19:05:101326 a[0] = (a[0] & 0x0f) | 0xe0;
drh8c559452023-09-22 11:20:351327 a[1] = (szPayload >> 24) & 0xff;
1328 a[2] = (szPayload >> 16) & 0xff;
1329 a[3] = (szPayload >> 8) & 0xff;
1330 a[4] = szPayload & 0xff;
1331 }
drhef97f832023-11-28 18:16:021332 return delta;
drh6831cad2023-09-21 17:51:391333}
1334
1335/*
drh09f23d22023-09-25 17:14:171336** If z[0] is 'u' and is followed by exactly 4 hexadecimal character,
1337** then set *pOp to JSONB_TEXTJ and return true. If not, do not make
1338** any changes to *pOp and return false.
1339*/
1340static int jsonIs4HexB(const char *z, int *pOp){
1341 if( z[0]!='u' ) return 0;
drh3262ca82023-12-19 21:39:581342 if( !jsonIs4Hex(&z[1]) ) return 0;
drh09f23d22023-09-25 17:14:171343 *pOp = JSONB_TEXTJ;
1344 return 1;
1345}
1346
drh7d2eaae2023-12-11 17:03:121347/*
1348** Check a single element of the JSONB in pParse for validity.
1349**
1350** The element to be checked starts at offset i and must end at on the
1351** last byte before iEnd.
1352**
1353** Return 0 if everything is correct. Return the 1-based byte offset of the
1354** error if a problem is detected. (In other words, if the error is at offset
1355** 0, return 1).
1356*/
drhad6bc612023-12-11 21:00:551357static u32 jsonbValidityCheck(
1358 const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */
1359 u32 i, /* Start of element as pParse->aBlob[i] */
1360 u32 iEnd, /* One more than the last byte of the element */
1361 u32 iDepth /* Current nesting depth */
1362){
drh7d2eaae2023-12-11 17:03:121363 u32 n, sz, j, k;
1364 const u8 *z;
1365 u8 x;
1366 if( iDepth>JSON_MAX_DEPTH ) return i+1;
1367 sz = 0;
1368 n = jsonbPayloadSize(pParse, i, &sz);
drh78e636b2023-12-12 17:13:101369 if( NEVER(n==0) ) return i+1; /* Checked by caller */
1370 if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */
drh7d2eaae2023-12-11 17:03:121371 z = pParse->aBlob;
1372 x = z[i] & 0x0f;
1373 switch( x ){
1374 case JSONB_NULL:
1375 case JSONB_TRUE:
1376 case JSONB_FALSE: {
1377 return n+sz==1 ? 0 : i+1;
1378 }
drh7d2eaae2023-12-11 17:03:121379 case JSONB_INT: {
1380 if( sz<1 ) return i+1;
1381 j = i+n;
1382 if( z[j]=='-' ){
1383 j++;
drhad6bc612023-12-11 21:00:551384 if( sz<2 ) return i+1;
drh7d2eaae2023-12-11 17:03:121385 }
1386 k = i+n+sz;
1387 while( j<k ){
1388 if( sqlite3Isdigit(z[j]) ){
1389 j++;
1390 }else{
1391 return j+1;
1392 }
1393 }
1394 return 0;
1395 }
1396 case JSONB_INT5: {
1397 if( sz<3 ) return i+1;
1398 j = i+n;
drhd2fd0992025-04-21 23:44:551399 if( z[j]=='-' ){
drh001caa72023-12-11 20:19:101400 if( sz<4 ) return i+1;
1401 j++;
1402 }
drhad6bc612023-12-11 21:00:551403 if( z[j]!='0' ) return i+1;
drh7d2eaae2023-12-11 17:03:121404 if( z[j+1]!='x' && z[j+1]!='X' ) return j+2;
1405 j += 2;
1406 k = i+n+sz;
1407 while( j<k ){
1408 if( sqlite3Isxdigit(z[j]) ){
1409 j++;
1410 }else{
1411 return j+1;
1412 }
1413 }
1414 return 0;
1415 }
1416 case JSONB_FLOAT:
1417 case JSONB_FLOAT5: {
1418 u8 seen = 0; /* 0: initial. 1: '.' seen 2: 'e' seen */
1419 if( sz<2 ) return i+1;
1420 j = i+n;
1421 k = j+sz;
1422 if( z[j]=='-' ){
1423 j++;
1424 if( sz<3 ) return i+1;
1425 }
1426 if( z[j]=='.' ){
drh87399a52023-12-12 14:33:521427 if( x==JSONB_FLOAT ) return j+1;
drhad6bc612023-12-11 21:00:551428 if( !sqlite3Isdigit(z[j+1]) ) return j+1;
drh7d2eaae2023-12-11 17:03:121429 j += 2;
1430 seen = 1;
1431 }else if( z[j]=='0' && x==JSONB_FLOAT ){
drhad6bc612023-12-11 21:00:551432 if( j+3>k ) return j+1;
1433 if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1;
1434 j++;
drh7d2eaae2023-12-11 17:03:121435 }
1436 for(; j<k; j++){
1437 if( sqlite3Isdigit(z[j]) ) continue;
1438 if( z[j]=='.' ){
drh87399a52023-12-12 14:33:521439 if( seen>0 ) return j+1;
drh7d2eaae2023-12-11 17:03:121440 if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){
drhad6bc612023-12-11 21:00:551441 return j+1;
drh7d2eaae2023-12-11 17:03:121442 }
1443 seen = 1;
1444 continue;
1445 }
1446 if( z[j]=='e' || z[j]=='E' ){
drhad6bc612023-12-11 21:00:551447 if( seen==2 ) return j+1;
1448 if( j==k-1 ) return j+1;
drh7d2eaae2023-12-11 17:03:121449 if( z[j+1]=='+' || z[j+1]=='-' ){
1450 j++;
drhad6bc612023-12-11 21:00:551451 if( j==k-1 ) return j+1;
drh7d2eaae2023-12-11 17:03:121452 }
1453 seen = 2;
1454 continue;
1455 }
drhad6bc612023-12-11 21:00:551456 return j+1;
drh7d2eaae2023-12-11 17:03:121457 }
drh87399a52023-12-12 14:33:521458 if( seen==0 ) return i+1;
drh7d2eaae2023-12-11 17:03:121459 return 0;
1460 }
1461 case JSONB_TEXT: {
drhcc1a39f2023-12-12 02:31:121462 j = i+n;
1463 k = j+sz;
1464 while( j<k ){
1465 if( !jsonIsOk[z[j]] && z[j]!='\'' ) return j+1;
1466 j++;
1467 }
drh7d2eaae2023-12-11 17:03:121468 return 0;
1469 }
1470 case JSONB_TEXTJ:
1471 case JSONB_TEXT5: {
drhcc1a39f2023-12-12 02:31:121472 j = i+n;
1473 k = j+sz;
1474 while( j<k ){
1475 if( !jsonIsOk[z[j]] && z[j]!='\'' ){
1476 if( z[j]=='"' ){
1477 if( x==JSONB_TEXTJ ) return j+1;
drhc24f5362024-01-31 13:46:441478 }else if( z[j]<=0x1f ){
1479 /* Control characters in JSON5 string literals are ok */
1480 if( x==JSONB_TEXTJ ) return j+1;
drh744581d2024-01-31 15:20:131481 }else if( NEVER(z[j]!='\\') || j+1>=k ){
drhcc1a39f2023-12-12 02:31:121482 return j+1;
1483 }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){
1484 j++;
1485 }else if( z[j+1]=='u' ){
1486 if( j+5>=k ) return j+1;
1487 if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1;
1488 j++;
1489 }else if( x!=JSONB_TEXT5 ){
1490 return j+1;
1491 }else{
1492 u32 c = 0;
1493 u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c);
drhb2b74902023-12-26 13:20:571494 if( c==JSON_INVALID_CHAR ) return j+1;
drhcc1a39f2023-12-12 02:31:121495 j += szC - 1;
1496 }
1497 }
1498 j++;
1499 }
drh7d2eaae2023-12-11 17:03:121500 return 0;
1501 }
1502 case JSONB_TEXTRAW: {
1503 return 0;
1504 }
1505 case JSONB_ARRAY: {
1506 u32 sub;
1507 j = i+n;
1508 k = j+sz;
1509 while( j<k ){
1510 sz = 0;
1511 n = jsonbPayloadSize(pParse, j, &sz);
1512 if( n==0 ) return j+1;
1513 if( j+n+sz>k ) return j+1;
1514 sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1);
1515 if( sub ) return sub;
1516 j += n + sz;
1517 }
1518 assert( j==k );
1519 return 0;
1520 }
1521 case JSONB_OBJECT: {
1522 u32 cnt = 0;
1523 u32 sub;
1524 j = i+n;
1525 k = j+sz;
1526 while( j<k ){
1527 sz = 0;
1528 n = jsonbPayloadSize(pParse, j, &sz);
1529 if( n==0 ) return j+1;
1530 if( j+n+sz>k ) return j+1;
1531 if( (cnt & 1)==0 ){
1532 x = z[j] & 0x0f;
1533 if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return j+1;
1534 }
1535 sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1);
1536 if( sub ) return sub;
1537 cnt++;
1538 j += n + sz;
1539 }
1540 assert( j==k );
1541 if( (cnt & 1)!=0 ) return j+1;
1542 return 0;
1543 }
drh87399a52023-12-12 14:33:521544 default: {
1545 return i+1;
1546 }
drh7d2eaae2023-12-11 17:03:121547 }
1548}
1549
drh09f23d22023-09-25 17:14:171550/*
drhf32aa342023-10-09 18:33:011551** Translate a single element of JSON text at pParse->zJson[i] into
1552** its equivalent binary JSONB representation. Append the translation into
1553** pParse->aBlob[] beginning at pParse->nBlob. The size of
drh6831cad2023-09-21 17:51:391554** pParse->aBlob[] is increased as necessary.
1555**
drhf32aa342023-10-09 18:33:011556** Return the index of the first character past the end of the element parsed,
drh6831cad2023-09-21 17:51:391557** or one of the following special result codes:
1558**
1559** 0 End of input
drh82136d92023-12-02 14:55:461560** -1 Syntax error or OOM
drhf7af8f32023-10-05 22:52:431561** -2 '}' seen \
1562** -3 ']' seen \___ For these returns, pParse->iErr is set to
1563** -4 ',' seen / the index in zJson[] of the seen character
1564** -5 ':' seen /
drh6831cad2023-09-21 17:51:391565*/
drh3262ca82023-12-19 21:39:581566static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){
drh6831cad2023-09-21 17:51:391567 char c;
1568 u32 j;
drh8c559452023-09-22 11:20:351569 u32 iThis, iStart;
drh6831cad2023-09-21 17:51:391570 int x;
1571 u8 t;
1572 const char *z = pParse->zJson;
1573json_parse_restart:
1574 switch( (u8)z[i] ){
1575 case '{': {
1576 /* Parse object */
drh6831cad2023-09-21 17:51:391577 iThis = pParse->nBlob;
drh2ff73a52023-12-04 01:14:231578 jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0);
drh6831cad2023-09-21 17:51:391579 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
1580 pParse->iErr = i;
1581 return -1;
1582 }
drh8c559452023-09-22 11:20:351583 iStart = pParse->nBlob;
drh6831cad2023-09-21 17:51:391584 for(j=i+1;;j++){
1585 u32 iBlob = pParse->nBlob;
drh3262ca82023-12-19 21:39:581586 x = jsonTranslateTextToBlob(pParse, j);
drh6831cad2023-09-21 17:51:391587 if( x<=0 ){
drh09f23d22023-09-25 17:14:171588 int op;
drh6831cad2023-09-21 17:51:391589 if( x==(-2) ){
1590 j = pParse->iErr;
drhe367e452023-09-22 16:20:481591 if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1;
drh6831cad2023-09-21 17:51:391592 break;
1593 }
1594 j += json5Whitespace(&z[j]);
drh09f23d22023-09-25 17:14:171595 op = JSONB_TEXT;
1596 if( sqlite3JsonId1(z[j])
1597 || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op))
drh6831cad2023-09-21 17:51:391598 ){
1599 int k = j+1;
1600 while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0)
drh09f23d22023-09-25 17:14:171601 || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op))
drh6831cad2023-09-21 17:51:391602 ){
1603 k++;
1604 }
1605 assert( iBlob==pParse->nBlob );
drh679c9082023-12-02 13:36:521606 jsonBlobAppendNode(pParse, op, k-j, &z[j]);
drh6831cad2023-09-21 17:51:391607 pParse->hasNonstd = 1;
1608 x = k;
1609 }else{
1610 if( x!=-1 ) pParse->iErr = j;
1611 return -1;
1612 }
1613 }
1614 if( pParse->oom ) return -1;
drh8c559452023-09-22 11:20:351615 t = pParse->aBlob[iBlob] & 0x0f;
drhc1c1d4d2023-09-22 14:33:391616 if( t<JSONB_TEXT || t>JSONB_TEXTRAW ){
drh6831cad2023-09-21 17:51:391617 pParse->iErr = j;
1618 return -1;
1619 }
1620 j = x;
1621 if( z[j]==':' ){
1622 j++;
1623 }else{
drhca1ce772023-12-01 12:57:121624 if( jsonIsspace(z[j]) ){
drh8eac91f2023-12-05 12:52:131625 /* strspn() is not helpful here */
drhca1ce772023-12-01 12:57:121626 do{ j++; }while( jsonIsspace(z[j]) );
drh6831cad2023-09-21 17:51:391627 if( z[j]==':' ){
1628 j++;
1629 goto parse_object_value;
1630 }
1631 }
drh3262ca82023-12-19 21:39:581632 x = jsonTranslateTextToBlob(pParse, j);
drh6831cad2023-09-21 17:51:391633 if( x!=(-5) ){
1634 if( x!=(-1) ) pParse->iErr = j;
1635 return -1;
1636 }
1637 j = pParse->iErr+1;
1638 }
1639 parse_object_value:
drh3262ca82023-12-19 21:39:581640 x = jsonTranslateTextToBlob(pParse, j);
drh6831cad2023-09-21 17:51:391641 if( x<=0 ){
1642 if( x!=(-1) ) pParse->iErr = j;
1643 return -1;
1644 }
1645 j = x;
1646 if( z[j]==',' ){
1647 continue;
1648 }else if( z[j]=='}' ){
1649 break;
1650 }else{
drhca1ce772023-12-01 12:57:121651 if( jsonIsspace(z[j]) ){
drh4a5c96a2023-12-14 15:38:571652 j += 1 + (u32)strspn(&z[j+1], jsonSpaces);
drh6831cad2023-09-21 17:51:391653 if( z[j]==',' ){
1654 continue;
1655 }else if( z[j]=='}' ){
1656 break;
1657 }
1658 }
drh3262ca82023-12-19 21:39:581659 x = jsonTranslateTextToBlob(pParse, j);
drh6831cad2023-09-21 17:51:391660 if( x==(-4) ){
1661 j = pParse->iErr;
1662 continue;
1663 }
1664 if( x==(-2) ){
1665 j = pParse->iErr;
1666 break;
1667 }
1668 }
1669 pParse->iErr = j;
1670 return -1;
1671 }
drha7e93862023-10-07 23:35:071672 jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart);
drh6831cad2023-09-21 17:51:391673 pParse->iDepth--;
1674 return j+1;
1675 }
1676 case '[': {
1677 /* Parse array */
drh6831cad2023-09-21 17:51:391678 iThis = pParse->nBlob;
mistachkinf7ad6842024-02-22 18:15:081679 assert( i<=(u32)pParse->nJson );
drh679c9082023-12-02 13:36:521680 jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0);
drh8c559452023-09-22 11:20:351681 iStart = pParse->nBlob;
drh6831cad2023-09-21 17:51:391682 if( pParse->oom ) return -1;
1683 if( ++pParse->iDepth > JSON_MAX_DEPTH ){
1684 pParse->iErr = i;
1685 return -1;
1686 }
1687 for(j=i+1;;j++){
drh3262ca82023-12-19 21:39:581688 x = jsonTranslateTextToBlob(pParse, j);
drh6831cad2023-09-21 17:51:391689 if( x<=0 ){
1690 if( x==(-3) ){
1691 j = pParse->iErr;
drhe367e452023-09-22 16:20:481692 if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1;
drh6831cad2023-09-21 17:51:391693 break;
1694 }
1695 if( x!=(-1) ) pParse->iErr = j;
1696 return -1;
1697 }
1698 j = x;
1699 if( z[j]==',' ){
1700 continue;
1701 }else if( z[j]==']' ){
1702 break;
1703 }else{
drhca1ce772023-12-01 12:57:121704 if( jsonIsspace(z[j]) ){
drh4a5c96a2023-12-14 15:38:571705 j += 1 + (u32)strspn(&z[j+1], jsonSpaces);
drh6831cad2023-09-21 17:51:391706 if( z[j]==',' ){
1707 continue;
1708 }else if( z[j]==']' ){
1709 break;
1710 }
1711 }
drh3262ca82023-12-19 21:39:581712 x = jsonTranslateTextToBlob(pParse, j);
drh6831cad2023-09-21 17:51:391713 if( x==(-4) ){
1714 j = pParse->iErr;
1715 continue;
1716 }
1717 if( x==(-3) ){
1718 j = pParse->iErr;
1719 break;
1720 }
1721 }
1722 pParse->iErr = j;
1723 return -1;
1724 }
drha7e93862023-10-07 23:35:071725 jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart);
drh6831cad2023-09-21 17:51:391726 pParse->iDepth--;
1727 return j+1;
1728 }
1729 case '\'': {
1730 u8 opcode;
1731 char cDelim;
1732 pParse->hasNonstd = 1;
drh8c559452023-09-22 11:20:351733 opcode = JSONB_TEXT;
drh6831cad2023-09-21 17:51:391734 goto parse_string;
1735 case '"':
1736 /* Parse string */
1737 opcode = JSONB_TEXT;
1738 parse_string:
1739 cDelim = z[i];
drh6df61982023-12-02 01:38:531740 j = i+1;
1741 while( 1 /*exit-by-break*/ ){
1742 if( jsonIsOk[(u8)z[j]] ){
drh590aaff2023-12-05 12:22:051743 if( !jsonIsOk[(u8)z[j+1]] ){
drh6df61982023-12-02 01:38:531744 j += 1;
drh590aaff2023-12-05 12:22:051745 }else if( !jsonIsOk[(u8)z[j+2]] ){
1746 j += 2;
1747 }else{
1748 j += 3;
1749 continue;
drh6df61982023-12-02 01:38:531750 }
1751 }
drh6831cad2023-09-21 17:51:391752 c = z[j];
1753 if( c==cDelim ){
1754 break;
1755 }else if( c=='\\' ){
1756 c = z[++j];
1757 if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
1758 || c=='n' || c=='r' || c=='t'
1759 || (c=='u' && jsonIs4Hex(&z[j+1])) ){
1760 if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ;
drh844b4572025-05-10 15:53:171761 }else if( c=='\'' || c=='v' || c=='\n'
drh94e22bc2025-05-10 17:09:531762#ifdef SQLITE_BUG_COMPATIBLE_20250510
1763 || (c=='0') /* Legacy bug compatible */
1764#else
1765 || (c=='0' && !sqlite3Isdigit(z[j+1])) /* Correct implementation */
1766#endif
drh6831cad2023-09-21 17:51:391767 || (0xe2==(u8)c && 0x80==(u8)z[j+1]
1768 && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]))
1769 || (c=='x' && jsonIs2Hex(&z[j+1])) ){
1770 opcode = JSONB_TEXT5;
1771 pParse->hasNonstd = 1;
1772 }else if( c=='\r' ){
1773 if( z[j+1]=='\n' ) j++;
1774 opcode = JSONB_TEXT5;
1775 pParse->hasNonstd = 1;
1776 }else{
1777 pParse->iErr = j;
1778 return -1;
1779 }
1780 }else if( c<=0x1f ){
drh94861782024-01-31 14:44:591781 if( c==0 ){
1782 pParse->iErr = j;
1783 return -1;
1784 }
drhc24f5362024-01-31 13:46:441785 /* Control characters are not allowed in canonical JSON string
1786 ** literals, but are allowed in JSON5 string literals. */
1787 opcode = JSONB_TEXT5;
1788 pParse->hasNonstd = 1;
drhcc1a39f2023-12-12 02:31:121789 }else if( c=='"' ){
1790 opcode = JSONB_TEXT5;
drh6831cad2023-09-21 17:51:391791 }
drh6df61982023-12-02 01:38:531792 j++;
drh6831cad2023-09-21 17:51:391793 }
drh679c9082023-12-02 13:36:521794 jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]);
drh6831cad2023-09-21 17:51:391795 return j+1;
1796 }
1797 case 't': {
1798 if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){
1799 jsonBlobAppendOneByte(pParse, JSONB_TRUE);
1800 return i+4;
1801 }
1802 pParse->iErr = i;
1803 return -1;
1804 }
1805 case 'f': {
1806 if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){
1807 jsonBlobAppendOneByte(pParse, JSONB_FALSE);
1808 return i+5;
1809 }
1810 pParse->iErr = i;
1811 return -1;
1812 }
1813 case '+': {
drh8c559452023-09-22 11:20:351814 u8 seenE;
drh6831cad2023-09-21 17:51:391815 pParse->hasNonstd = 1;
drhc1c1d4d2023-09-22 14:33:391816 t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
drh6831cad2023-09-21 17:51:391817 goto parse_number;
1818 case '.':
1819 if( sqlite3Isdigit(z[i+1]) ){
1820 pParse->hasNonstd = 1;
drh8c559452023-09-22 11:20:351821 t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
drh6831cad2023-09-21 17:51:391822 seenE = 0;
drh6831cad2023-09-21 17:51:391823 goto parse_number_2;
1824 }
1825 pParse->iErr = i;
1826 return -1;
1827 case '-':
1828 case '0':
1829 case '1':
1830 case '2':
1831 case '3':
1832 case '4':
1833 case '5':
1834 case '6':
1835 case '7':
1836 case '8':
1837 case '9':
1838 /* Parse number */
drh8c559452023-09-22 11:20:351839 t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */
drh6831cad2023-09-21 17:51:391840 parse_number:
drh6831cad2023-09-21 17:51:391841 seenE = 0;
1842 assert( '-' < '0' );
1843 assert( '+' < '0' );
1844 assert( '.' < '0' );
1845 c = z[i];
1846
1847 if( c<='0' ){
1848 if( c=='0' ){
1849 if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){
drh8c559452023-09-22 11:20:351850 assert( t==0x00 );
drh6831cad2023-09-21 17:51:391851 pParse->hasNonstd = 1;
drh8c559452023-09-22 11:20:351852 t = 0x01;
drh6831cad2023-09-21 17:51:391853 for(j=i+3; sqlite3Isxdigit(z[j]); j++){}
1854 goto parse_number_finish;
1855 }else if( sqlite3Isdigit(z[i+1]) ){
1856 pParse->iErr = i+1;
1857 return -1;
1858 }
1859 }else{
1860 if( !sqlite3Isdigit(z[i+1]) ){
1861 /* JSON5 allows for "+Infinity" and "-Infinity" using exactly
1862 ** that case. SQLite also allows these in any case and it allows
1863 ** "+inf" and "-inf". */
1864 if( (z[i+1]=='I' || z[i+1]=='i')
1865 && sqlite3StrNICmp(&z[i+1], "inf",3)==0
1866 ){
1867 pParse->hasNonstd = 1;
drh6831cad2023-09-21 17:51:391868 if( z[i]=='-' ){
drh679c9082023-12-02 13:36:521869 jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999");
drh6831cad2023-09-21 17:51:391870 }else{
drh679c9082023-12-02 13:36:521871 jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
drh6831cad2023-09-21 17:51:391872 }
1873 return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4);
1874 }
1875 if( z[i+1]=='.' ){
1876 pParse->hasNonstd = 1;
drh14fce242023-10-05 17:52:391877 t |= 0x01;
drh6831cad2023-09-21 17:51:391878 goto parse_number_2;
1879 }
1880 pParse->iErr = i;
1881 return -1;
1882 }
1883 if( z[i+1]=='0' ){
1884 if( sqlite3Isdigit(z[i+2]) ){
1885 pParse->iErr = i+1;
1886 return -1;
1887 }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){
1888 pParse->hasNonstd = 1;
drh8c559452023-09-22 11:20:351889 t |= 0x01;
drh6831cad2023-09-21 17:51:391890 for(j=i+4; sqlite3Isxdigit(z[j]); j++){}
1891 goto parse_number_finish;
1892 }
1893 }
1894 }
1895 }
drhe1e2f2d2023-10-06 14:52:491896
drh6831cad2023-09-21 17:51:391897 parse_number_2:
1898 for(j=i+1;; j++){
1899 c = z[j];
1900 if( sqlite3Isdigit(c) ) continue;
1901 if( c=='.' ){
drh8c559452023-09-22 11:20:351902 if( (t & 0x02)!=0 ){
drh6831cad2023-09-21 17:51:391903 pParse->iErr = j;
1904 return -1;
1905 }
drh8c559452023-09-22 11:20:351906 t |= 0x02;
drh6831cad2023-09-21 17:51:391907 continue;
1908 }
1909 if( c=='e' || c=='E' ){
1910 if( z[j-1]<'0' ){
1911 if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
1912 pParse->hasNonstd = 1;
drh8c559452023-09-22 11:20:351913 t |= 0x01;
drh6831cad2023-09-21 17:51:391914 }else{
1915 pParse->iErr = j;
1916 return -1;
1917 }
1918 }
1919 if( seenE ){
1920 pParse->iErr = j;
1921 return -1;
1922 }
drh8c559452023-09-22 11:20:351923 t |= 0x02;
drh6831cad2023-09-21 17:51:391924 seenE = 1;
1925 c = z[j+1];
1926 if( c=='+' || c=='-' ){
1927 j++;
1928 c = z[j+1];
1929 }
1930 if( c<'0' || c>'9' ){
1931 pParse->iErr = j;
1932 return -1;
1933 }
1934 continue;
1935 }
1936 break;
1937 }
1938 if( z[j-1]<'0' ){
1939 if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
1940 pParse->hasNonstd = 1;
drh8c559452023-09-22 11:20:351941 t |= 0x01;
drh6831cad2023-09-21 17:51:391942 }else{
1943 pParse->iErr = j;
1944 return -1;
1945 }
1946 }
1947 parse_number_finish:
drh8c559452023-09-22 11:20:351948 assert( JSONB_INT+0x01==JSONB_INT5 );
1949 assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 );
1950 assert( JSONB_INT+0x02==JSONB_FLOAT );
drhc1c1d4d2023-09-22 14:33:391951 if( z[i]=='+' ) i++;
drh679c9082023-12-02 13:36:521952 jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]);
drh6831cad2023-09-21 17:51:391953 return j;
1954 }
1955 case '}': {
1956 pParse->iErr = i;
1957 return -2; /* End of {...} */
1958 }
1959 case ']': {
1960 pParse->iErr = i;
1961 return -3; /* End of [...] */
1962 }
1963 case ',': {
1964 pParse->iErr = i;
1965 return -4; /* List separator */
1966 }
1967 case ':': {
1968 pParse->iErr = i;
1969 return -5; /* Object label/value separator */
1970 }
1971 case 0: {
1972 return 0; /* End of file */
1973 }
1974 case 0x09:
1975 case 0x0a:
1976 case 0x0d:
1977 case 0x20: {
drh4a5c96a2023-12-14 15:38:571978 i += 1 + (u32)strspn(&z[i+1], jsonSpaces);
drh6831cad2023-09-21 17:51:391979 goto json_parse_restart;
1980 }
1981 case 0x0b:
1982 case 0x0c:
1983 case '/':
1984 case 0xc2:
1985 case 0xe1:
1986 case 0xe2:
1987 case 0xe3:
1988 case 0xef: {
1989 j = json5Whitespace(&z[i]);
1990 if( j>0 ){
1991 i += j;
1992 pParse->hasNonstd = 1;
1993 goto json_parse_restart;
1994 }
1995 pParse->iErr = i;
1996 return -1;
1997 }
1998 case 'n': {
1999 if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){
2000 jsonBlobAppendOneByte(pParse, JSONB_NULL);
2001 return i+4;
2002 }
2003 /* fall-through into the default case that checks for NaN */
drh6ad928d2024-01-16 15:04:192004 /* no break */ deliberate_fall_through
drh6831cad2023-09-21 17:51:392005 }
2006 default: {
2007 u32 k;
2008 int nn;
2009 c = z[i];
2010 for(k=0; k<sizeof(aNanInfName)/sizeof(aNanInfName[0]); k++){
2011 if( c!=aNanInfName[k].c1 && c!=aNanInfName[k].c2 ) continue;
2012 nn = aNanInfName[k].n;
2013 if( sqlite3StrNICmp(&z[i], aNanInfName[k].zMatch, nn)!=0 ){
2014 continue;
2015 }
2016 if( sqlite3Isalnum(z[i+nn]) ) continue;
drh4b9ed1b2023-11-30 23:36:142017 if( aNanInfName[k].eType==JSONB_FLOAT ){
drh679c9082023-12-02 13:36:522018 jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
drh6831cad2023-09-21 17:51:392019 }else{
2020 jsonBlobAppendOneByte(pParse, JSONB_NULL);
2021 }
2022 pParse->hasNonstd = 1;
2023 return i + nn;
2024 }
2025 pParse->iErr = i;
2026 return -1; /* Syntax error */
2027 }
2028 } /* End switch(z[i]) */
2029}
2030
drh440e6962023-07-25 18:28:032031
drh505ad2c2015-08-21 17:33:112032/*
drh6831cad2023-09-21 17:51:392033** Parse a complete JSON string. Return 0 on success or non-zero if there
2034** are any errors. If an error occurs, free all memory held by pParse,
2035** but not pParse itself.
2036**
2037** pParse must be initialized to an empty parse object prior to calling
2038** this routine.
2039*/
drha99e2fb2023-09-29 16:37:222040static int jsonConvertTextToBlob(
drh6831cad2023-09-21 17:51:392041 JsonParse *pParse, /* Initialize and fill this JsonParse object */
2042 sqlite3_context *pCtx /* Report errors here */
2043){
2044 int i;
2045 const char *zJson = pParse->zJson;
drh3262ca82023-12-19 21:39:582046 i = jsonTranslateTextToBlob(pParse, 0);
drh6831cad2023-09-21 17:51:392047 if( pParse->oom ) i = -1;
2048 if( i>0 ){
drh7d2eaae2023-12-11 17:03:122049#ifdef SQLITE_DEBUG
drh6831cad2023-09-21 17:51:392050 assert( pParse->iDepth==0 );
drhba550562023-12-11 19:00:442051 if( sqlite3Config.bJsonSelfcheck ){
drh7d2eaae2023-12-11 17:03:122052 assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 );
2053 }
2054#endif
drhca1ce772023-12-01 12:57:122055 while( jsonIsspace(zJson[i]) ) i++;
drh6831cad2023-09-21 17:51:392056 if( zJson[i] ){
2057 i += json5Whitespace(&zJson[i]);
2058 if( zJson[i] ){
drh9af45dc2023-12-03 23:38:242059 if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1);
drh6831cad2023-09-21 17:51:392060 jsonParseReset(pParse);
2061 return 1;
2062 }
2063 pParse->hasNonstd = 1;
2064 }
2065 }
2066 if( i<=0 ){
drh796abda2023-11-25 20:59:032067 if( pCtx!=0 ){
drh6831cad2023-09-21 17:51:392068 if( pParse->oom ){
2069 sqlite3_result_error_nomem(pCtx);
2070 }else{
2071 sqlite3_result_error(pCtx, "malformed JSON", -1);
2072 }
2073 }
2074 jsonParseReset(pParse);
2075 return 1;
2076 }
2077 return 0;
2078}
2079
drh7e86d3f2023-09-30 14:34:392080/*
2081** The input string pStr is a well-formed JSON text string. Convert
2082** this into the JSONB format and make it the return value of the
2083** SQL function.
2084*/
2085static void jsonReturnStringAsBlob(JsonString *pStr){
2086 JsonParse px;
2087 memset(&px, 0, sizeof(px));
drh86db4552023-10-11 13:19:372088 jsonStringTerminate(pStr);
drh71cdea82024-02-07 14:05:382089 if( pStr->eErr ){
2090 sqlite3_result_error_nomem(pStr->pCtx);
2091 return;
2092 }
drh7e86d3f2023-09-30 14:34:392093 px.zJson = pStr->zBuf;
2094 px.nJson = pStr->nUsed;
drh4093b292024-01-03 16:41:502095 px.db = sqlite3_context_db_handle(pStr->pCtx);
drh3262ca82023-12-19 21:39:582096 (void)jsonTranslateTextToBlob(&px, 0);
drh7e86d3f2023-09-30 14:34:392097 if( px.oom ){
drh4093b292024-01-03 16:41:502098 sqlite3DbFree(px.db, px.aBlob);
drh7e86d3f2023-09-30 14:34:392099 sqlite3_result_error_nomem(pStr->pCtx);
2100 }else{
drha11aaff2023-12-02 18:04:272101 assert( px.nBlobAlloc>0 );
2102 assert( !px.bReadOnly );
drh4093b292024-01-03 16:41:502103 sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC);
drh7e86d3f2023-09-30 14:34:392104 }
2105}
2106
drh90189be2023-09-22 12:16:562107/* The byte at index i is a node type-code. This routine
2108** determines the payload size for that node and writes that
drhc1c1d4d2023-09-22 14:33:392109** payload size in to *pSz. It returns the offset from i to the
drh59335812023-09-25 13:23:292110** beginning of the payload. Return 0 on error.
drh90189be2023-09-22 12:16:562111*/
drh5026ddb2023-11-28 12:28:282112static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
drh90189be2023-09-22 12:16:562113 u8 x;
2114 u32 sz;
2115 u32 n;
drha0d35d42025-02-10 11:16:372116 assert( i<=pParse->nBlob );
drh90189be2023-09-22 12:16:562117 x = pParse->aBlob[i]>>4;
2118 if( x<=11 ){
2119 sz = x;
drhc1c1d4d2023-09-22 14:33:392120 n = 1;
drh90189be2023-09-22 12:16:562121 }else if( x==12 ){
drh7b434972023-10-06 18:21:472122 if( i+1>=pParse->nBlob ){
drh90189be2023-09-22 12:16:562123 *pSz = 0;
drh59335812023-09-25 13:23:292124 return 0;
drh90189be2023-09-22 12:16:562125 }
2126 sz = pParse->aBlob[i+1];
drhc1c1d4d2023-09-22 14:33:392127 n = 2;
drh90189be2023-09-22 12:16:562128 }else if( x==13 ){
drh7b434972023-10-06 18:21:472129 if( i+2>=pParse->nBlob ){
drh90189be2023-09-22 12:16:562130 *pSz = 0;
drh59335812023-09-25 13:23:292131 return 0;
drh90189be2023-09-22 12:16:562132 }
2133 sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2];
drhc1c1d4d2023-09-22 14:33:392134 n = 3;
drhb597fea2023-12-06 17:39:312135 }else if( x==14 ){
drh7b434972023-10-06 18:21:472136 if( i+4>=pParse->nBlob ){
drh90189be2023-09-22 12:16:562137 *pSz = 0;
drh59335812023-09-25 13:23:292138 return 0;
drh90189be2023-09-22 12:16:562139 }
drhbfa0de82023-12-08 16:56:502140 sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) +
drh90189be2023-09-22 12:16:562141 (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4];
drhc1c1d4d2023-09-22 14:33:392142 n = 5;
drhb597fea2023-12-06 17:39:312143 }else{
2144 if( i+8>=pParse->nBlob
2145 || pParse->aBlob[i+1]!=0
2146 || pParse->aBlob[i+2]!=0
2147 || pParse->aBlob[i+3]!=0
2148 || pParse->aBlob[i+4]!=0
2149 ){
2150 *pSz = 0;
2151 return 0;
2152 }
drhf087b6a2025-05-07 17:13:302153 sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
drhb597fea2023-12-06 17:39:312154 (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
2155 n = 9;
drh90189be2023-09-22 12:16:562156 }
dan7f9a1ff2024-01-29 15:30:352157 if( (i64)i+sz+n > pParse->nBlob
2158 && (i64)i+sz+n > pParse->nBlob-pParse->delta
drhda257832023-11-29 17:36:542159 ){
drha0d35d42025-02-10 11:16:372160 *pSz = 0;
2161 return 0;
drh90189be2023-09-22 12:16:562162 }
2163 *pSz = sz;
2164 return n;
2165}
2166
2167
drh8c559452023-09-22 11:20:352168/*
drhf32aa342023-10-09 18:33:012169** Translate the binary JSONB representation of JSON beginning at
2170** pParse->aBlob[i] into a JSON text string. Append the JSON
2171** text onto the end of pOut. Return the index in pParse->aBlob[]
2172** of the first byte past the end of the element that is translated.
drh7b434972023-10-06 18:21:472173**
2174** If an error is detected in the BLOB input, the pOut->eErr flag
2175** might get set to JSTRING_MALFORMED. But not all BLOB input errors
2176** are detected. So a malformed JSONB input might either result
2177** in an error, or in incorrect JSON.
2178**
2179** The pOut->eErr JSTRING_OOM flag is set on a OOM.
drh8c559452023-09-22 11:20:352180*/
drh3262ca82023-12-19 21:39:582181static u32 jsonTranslateBlobToText(
drh5026ddb2023-11-28 12:28:282182 const JsonParse *pParse, /* the complete parse of the JSON */
drh90189be2023-09-22 12:16:562183 u32 i, /* Start rendering at this index */
drh8c559452023-09-22 11:20:352184 JsonString *pOut /* Write JSON here */
2185){
drhc1c1d4d2023-09-22 14:33:392186 u32 sz, n, j, iEnd;
2187
drh8eeafb72023-10-02 13:20:432188 n = jsonbPayloadSize(pParse, i, &sz);
2189 if( n==0 ){
drhe1e2f2d2023-10-06 14:52:492190 pOut->eErr |= JSTRING_MALFORMED;
drh8eeafb72023-10-02 13:20:432191 return pParse->nBlob+1;
drh8c559452023-09-22 11:20:352192 }
drh90189be2023-09-22 12:16:562193 switch( pParse->aBlob[i] & 0x0f ){
2194 case JSONB_NULL: {
drh8c559452023-09-22 11:20:352195 jsonAppendRawNZ(pOut, "null", 4);
drh90189be2023-09-22 12:16:562196 return i+1;
drh8c559452023-09-22 11:20:352197 }
2198 case JSONB_TRUE: {
2199 jsonAppendRawNZ(pOut, "true", 4);
drh90189be2023-09-22 12:16:562200 return i+1;
drh8c559452023-09-22 11:20:352201 }
2202 case JSONB_FALSE: {
2203 jsonAppendRawNZ(pOut, "false", 5);
drh90189be2023-09-22 12:16:562204 return i+1;
drh8c559452023-09-22 11:20:352205 }
drh90189be2023-09-22 12:16:562206 case JSONB_INT:
drhc1c1d4d2023-09-22 14:33:392207 case JSONB_FLOAT: {
drh3fc7a342024-01-29 12:50:322208 if( sz==0 ) goto malformed_jsonb;
drhc1c1d4d2023-09-22 14:33:392209 jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz);
2210 break;
2211 }
2212 case JSONB_INT5: { /* Integer literal in hexadecimal notation */
drhe690d5a2023-10-06 14:59:402213 u32 k = 2;
drhc1c1d4d2023-09-22 14:33:392214 sqlite3_uint64 u = 0;
drhc1c1d4d2023-09-22 14:33:392215 const char *zIn = (const char*)&pParse->aBlob[i+n];
drhe1df37b2023-11-21 19:05:222216 int bOverflow = 0;
drh3fc7a342024-01-29 12:50:322217 if( sz==0 ) goto malformed_jsonb;
drh7b434972023-10-06 18:21:472218 if( zIn[0]=='-' ){
2219 jsonAppendChar(pOut, '-');
drhe1e2f2d2023-10-06 14:52:492220 k++;
drh664fe312023-11-21 18:23:432221 }else if( zIn[0]=='+' ){
2222 k++;
drhc1c1d4d2023-09-22 14:33:392223 }
drhe1e2f2d2023-10-06 14:52:492224 for(; k<sz; k++){
drh7b434972023-10-06 18:21:472225 if( !sqlite3Isxdigit(zIn[k]) ){
2226 pOut->eErr |= JSTRING_MALFORMED;
drh6b8aa952023-10-06 22:16:092227 break;
drhe1df37b2023-11-21 19:05:222228 }else if( (u>>60)!=0 ){
2229 bOverflow = 1;
drh6b8aa952023-10-06 22:16:092230 }else{
2231 u = u*16 + sqlite3HexToInt(zIn[k]);
drh7b434972023-10-06 18:21:472232 }
drhc1c1d4d2023-09-22 14:33:392233 }
drhe1df37b2023-11-21 19:05:222234 jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u);
drhc1c1d4d2023-09-22 14:33:392235 break;
2236 }
2237 case JSONB_FLOAT5: { /* Float literal missing digits beside "." */
drhe690d5a2023-10-06 14:59:402238 u32 k = 0;
drhc1c1d4d2023-09-22 14:33:392239 const char *zIn = (const char*)&pParse->aBlob[i+n];
drh3fc7a342024-01-29 12:50:322240 if( sz==0 ) goto malformed_jsonb;
drh7b434972023-10-06 18:21:472241 if( zIn[0]=='-' ){
2242 jsonAppendChar(pOut, '-');
drhe1e2f2d2023-10-06 14:52:492243 k++;
drhc1c1d4d2023-09-22 14:33:392244 }
drhe1e2f2d2023-10-06 14:52:492245 if( zIn[k]=='.' ){
drhc1c1d4d2023-09-22 14:33:392246 jsonAppendChar(pOut, '0');
2247 }
drhe1e2f2d2023-10-06 14:52:492248 for(; k<sz; k++){
2249 jsonAppendChar(pOut, zIn[k]);
drhc1c1d4d2023-09-22 14:33:392250 if( zIn[k]=='.' && (k+1==sz || !sqlite3Isdigit(zIn[k+1])) ){
drhc1c1d4d2023-09-22 14:33:392251 jsonAppendChar(pOut, '0');
drhc1c1d4d2023-09-22 14:33:392252 }
2253 }
drhc1c1d4d2023-09-22 14:33:392254 break;
2255 }
drhcc1a39f2023-12-12 02:31:122256 case JSONB_TEXT:
drhc1c1d4d2023-09-22 14:33:392257 case JSONB_TEXTJ: {
drh93df8102025-02-10 00:20:502258 if( pOut->nUsed+sz+2<=pOut->nAlloc || jsonStringGrow(pOut, sz+2)==0 ){
2259 pOut->zBuf[pOut->nUsed] = '"';
2260 memcpy(pOut->zBuf+pOut->nUsed+1,(const char*)&pParse->aBlob[i+n],sz);
2261 pOut->zBuf[pOut->nUsed+sz+1] = '"';
2262 pOut->nUsed += sz+2;
2263 }
drhc1c1d4d2023-09-22 14:33:392264 break;
2265 }
2266 case JSONB_TEXT5: {
2267 const char *zIn;
2268 u32 k;
drh98dbfa62023-10-06 15:35:422269 u32 sz2 = sz;
drhc1c1d4d2023-09-22 14:33:392270 zIn = (const char*)&pParse->aBlob[i+n];
2271 jsonAppendChar(pOut, '"');
drh98dbfa62023-10-06 15:35:422272 while( sz2>0 ){
drhc24f5362024-01-31 13:46:442273 for(k=0; k<sz2 && (jsonIsOk[(u8)zIn[k]] || zIn[k]=='\''); k++){}
drhc1c1d4d2023-09-22 14:33:392274 if( k>0 ){
2275 jsonAppendRawNZ(pOut, zIn, k);
drh71dc3c72023-10-10 23:02:312276 if( k>=sz2 ){
drh59ded6b2023-10-10 18:42:082277 break;
2278 }
drhc1c1d4d2023-09-22 14:33:392279 zIn += k;
drh98dbfa62023-10-06 15:35:422280 sz2 -= k;
drhc1c1d4d2023-09-22 14:33:392281 }
drhef97f832023-11-28 18:16:022282 if( zIn[0]=='"' ){
2283 jsonAppendRawNZ(pOut, "\\\"", 2);
2284 zIn++;
2285 sz2--;
2286 continue;
2287 }
drhc24f5362024-01-31 13:46:442288 if( zIn[0]<=0x1f ){
drh744581d2024-01-31 15:20:132289 if( pOut->nUsed+7>pOut->nAlloc && jsonStringGrow(pOut,7) ) break;
drhc24f5362024-01-31 13:46:442290 jsonAppendControlChar(pOut, zIn[0]);
2291 zIn++;
2292 sz2--;
2293 continue;
2294 }
drhc1c1d4d2023-09-22 14:33:392295 assert( zIn[0]=='\\' );
drhdc138cb2023-12-04 13:12:452296 assert( sz2>=1 );
2297 if( sz2<2 ){
2298 pOut->eErr |= JSTRING_MALFORMED;
2299 break;
2300 }
drhc1c1d4d2023-09-22 14:33:392301 switch( (u8)zIn[1] ){
2302 case '\'':
2303 jsonAppendChar(pOut, '\'');
2304 break;
2305 case 'v':
2306 jsonAppendRawNZ(pOut, "\\u0009", 6);
2307 break;
2308 case 'x':
drhdc138cb2023-12-04 13:12:452309 if( sz2<4 ){
drh59ded6b2023-10-10 18:42:082310 pOut->eErr |= JSTRING_MALFORMED;
drhdc138cb2023-12-04 13:12:452311 sz2 = 2;
drh71dc3c72023-10-10 23:02:312312 break;
drh064c1682023-10-10 18:04:402313 }
drh71dc3c72023-10-10 23:02:312314 jsonAppendRawNZ(pOut, "\\u00", 4);
2315 jsonAppendRawNZ(pOut, &zIn[2], 2);
2316 zIn += 2;
2317 sz2 -= 2;
drhc1c1d4d2023-09-22 14:33:392318 break;
2319 case '0':
2320 jsonAppendRawNZ(pOut, "\\u0000", 6);
2321 break;
2322 case '\r':
drh71dc3c72023-10-10 23:02:312323 if( sz2>2 && zIn[2]=='\n' ){
drhc1c1d4d2023-09-22 14:33:392324 zIn++;
drh98dbfa62023-10-06 15:35:422325 sz2--;
drhc1c1d4d2023-09-22 14:33:392326 }
2327 break;
2328 case '\n':
2329 break;
2330 case 0xe2:
drh71dc3c72023-10-10 23:02:312331 /* '\' followed by either U+2028 or U+2029 is ignored as
2332 ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29.
2333 ** U+2029 is the same except for the last byte */
drh59ded6b2023-10-10 18:42:082334 if( sz2<4
2335 || 0x80!=(u8)zIn[2]
2336 || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3])
2337 ){
2338 pOut->eErr |= JSTRING_MALFORMED;
drhdc138cb2023-12-04 13:12:452339 sz2 = 2;
drh59ded6b2023-10-10 18:42:082340 break;
2341 }
drhc1c1d4d2023-09-22 14:33:392342 zIn += 2;
drh98dbfa62023-10-06 15:35:422343 sz2 -= 2;
drhc1c1d4d2023-09-22 14:33:392344 break;
2345 default:
2346 jsonAppendRawNZ(pOut, zIn, 2);
2347 break;
2348 }
drhdc138cb2023-12-04 13:12:452349 assert( sz2>=2 );
drhc1c1d4d2023-09-22 14:33:392350 zIn += 2;
drh98dbfa62023-10-06 15:35:422351 sz2 -= 2;
drhc1c1d4d2023-09-22 14:33:392352 }
2353 jsonAppendChar(pOut, '"');
2354 break;
2355 }
drh11aa2ad2023-10-06 23:02:062356 case JSONB_TEXTRAW: {
2357 jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz);
2358 break;
2359 }
drhc1c1d4d2023-09-22 14:33:392360 case JSONB_ARRAY: {
2361 jsonAppendChar(pOut, '[');
drhc1c1d4d2023-09-22 14:33:392362 j = i+n;
2363 iEnd = j+sz;
drhaf3824d2024-01-29 20:36:172364 while( j<iEnd && pOut->eErr==0 ){
drh3262ca82023-12-19 21:39:582365 j = jsonTranslateBlobToText(pParse, j, pOut);
drhc1c1d4d2023-09-22 14:33:392366 jsonAppendChar(pOut, ',');
2367 }
drh91981fe2024-01-29 21:09:562368 if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED;
drh777a0882024-01-20 12:13:002369 if( sz>0 ) jsonStringTrimOneChar(pOut);
drhc1c1d4d2023-09-22 14:33:392370 jsonAppendChar(pOut, ']');
2371 break;
2372 }
2373 case JSONB_OBJECT: {
2374 int x = 0;
2375 jsonAppendChar(pOut, '{');
drhc1c1d4d2023-09-22 14:33:392376 j = i+n;
2377 iEnd = j+sz;
drhaf3824d2024-01-29 20:36:172378 while( j<iEnd && pOut->eErr==0 ){
drh3262ca82023-12-19 21:39:582379 j = jsonTranslateBlobToText(pParse, j, pOut);
drhc1c1d4d2023-09-22 14:33:392380 jsonAppendChar(pOut, (x++ & 1) ? ',' : ':');
2381 }
drh91981fe2024-01-29 21:09:562382 if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED;
drh777a0882024-01-20 12:13:002383 if( sz>0 ) jsonStringTrimOneChar(pOut);
drhc1c1d4d2023-09-22 14:33:392384 jsonAppendChar(pOut, '}');
2385 break;
drh90189be2023-09-22 12:16:562386 }
drh8c559452023-09-22 11:20:352387
drh8c559452023-09-22 11:20:352388 default: {
drh3fc7a342024-01-29 12:50:322389 malformed_jsonb:
drh98dbfa62023-10-06 15:35:422390 pOut->eErr |= JSTRING_MALFORMED;
drh8c559452023-09-22 11:20:352391 break;
2392 }
2393 }
drhc1c1d4d2023-09-22 14:33:392394 return i+n+sz;
drh8c559452023-09-22 11:20:352395}
drh90189be2023-09-22 12:16:562396
drhb4e7d592024-03-06 14:30:422397/* Context for recursion of json_pretty()
2398*/
2399typedef struct JsonPretty JsonPretty;
2400struct JsonPretty {
2401 JsonParse *pParse; /* The BLOB being rendered */
2402 JsonString *pOut; /* Generate pretty output into this string */
2403 const char *zIndent; /* Use this text for indentation */
2404 u32 szIndent; /* Bytes in zIndent[] */
2405 u32 nIndent; /* Current level of indentation */
2406};
2407
2408/* Append indentation to the pretty JSON under construction */
2409static void jsonPrettyIndent(JsonPretty *pPretty){
2410 u32 jj;
2411 for(jj=0; jj<pPretty->nIndent; jj++){
2412 jsonAppendRaw(pPretty->pOut, pPretty->zIndent, pPretty->szIndent);
2413 }
2414}
2415
2416/*
2417** Translate the binary JSONB representation of JSON beginning at
2418** pParse->aBlob[i] into a JSON text string. Append the JSON
2419** text onto the end of pOut. Return the index in pParse->aBlob[]
2420** of the first byte past the end of the element that is translated.
2421**
2422** This is a variant of jsonTranslateBlobToText() that "pretty-prints"
2423** the output. Extra whitespace is inserted to make the JSON easier
2424** for humans to read.
2425**
2426** If an error is detected in the BLOB input, the pOut->eErr flag
2427** might get set to JSTRING_MALFORMED. But not all BLOB input errors
2428** are detected. So a malformed JSONB input might either result
2429** in an error, or in incorrect JSON.
2430**
2431** The pOut->eErr JSTRING_OOM flag is set on a OOM.
2432*/
2433static u32 jsonTranslateBlobToPrettyText(
2434 JsonPretty *pPretty, /* Pretty-printing context */
2435 u32 i /* Start rendering at this index */
2436){
2437 u32 sz, n, j, iEnd;
2438 const JsonParse *pParse = pPretty->pParse;
2439 JsonString *pOut = pPretty->pOut;
2440 n = jsonbPayloadSize(pParse, i, &sz);
2441 if( n==0 ){
2442 pOut->eErr |= JSTRING_MALFORMED;
2443 return pParse->nBlob+1;
2444 }
2445 switch( pParse->aBlob[i] & 0x0f ){
2446 case JSONB_ARRAY: {
2447 j = i+n;
2448 iEnd = j+sz;
2449 jsonAppendChar(pOut, '[');
2450 if( j<iEnd ){
2451 jsonAppendChar(pOut, '\n');
2452 pPretty->nIndent++;
2453 while( pOut->eErr==0 ){
2454 jsonPrettyIndent(pPretty);
2455 j = jsonTranslateBlobToPrettyText(pPretty, j);
2456 if( j>=iEnd ) break;
2457 jsonAppendRawNZ(pOut, ",\n", 2);
2458 }
2459 jsonAppendChar(pOut, '\n');
2460 pPretty->nIndent--;
2461 jsonPrettyIndent(pPretty);
2462 }
2463 jsonAppendChar(pOut, ']');
2464 i = iEnd;
2465 break;
2466 }
2467 case JSONB_OBJECT: {
2468 j = i+n;
2469 iEnd = j+sz;
2470 jsonAppendChar(pOut, '{');
2471 if( j<iEnd ){
2472 jsonAppendChar(pOut, '\n');
2473 pPretty->nIndent++;
2474 while( pOut->eErr==0 ){
2475 jsonPrettyIndent(pPretty);
2476 j = jsonTranslateBlobToText(pParse, j, pOut);
2477 if( j>iEnd ){
2478 pOut->eErr |= JSTRING_MALFORMED;
2479 break;
2480 }
2481 jsonAppendRawNZ(pOut, ": ", 2);
2482 j = jsonTranslateBlobToPrettyText(pPretty, j);
2483 if( j>=iEnd ) break;
2484 jsonAppendRawNZ(pOut, ",\n", 2);
2485 }
2486 jsonAppendChar(pOut, '\n');
2487 pPretty->nIndent--;
2488 jsonPrettyIndent(pPretty);
2489 }
2490 jsonAppendChar(pOut, '}');
2491 i = iEnd;
2492 break;
2493 }
2494 default: {
2495 i = jsonTranslateBlobToText(pParse, i, pOut);
2496 break;
2497 }
2498 }
2499 return i;
2500}
2501
drh42156fd2023-09-26 19:30:462502/*
drh6b1db922023-09-28 17:23:462503** Given that a JSONB_ARRAY object starts at offset i, return
2504** the number of entries in that array.
2505*/
2506static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){
2507 u32 n, sz, i, iEnd;
2508 u32 k = 0;
2509 n = jsonbPayloadSize(pParse, iRoot, &sz);
2510 iEnd = iRoot+n+sz;
drh8eeafb72023-10-02 13:20:432511 for(i=iRoot+n; n>0 && i<iEnd; i+=sz+n, k++){
drh6b1db922023-09-28 17:23:462512 n = jsonbPayloadSize(pParse, i, &sz);
2513 }
2514 return k;
2515}
2516
2517/*
drhc1e85742023-12-02 20:25:362518** Edit the payload size of the element at iRoot by the amount in
2519** pParse->delta.
drh7b5123c2023-11-03 12:09:222520*/
2521static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){
drh03999942023-11-15 16:10:312522 u32 sz = 0;
drhaf0c9ff2023-11-15 18:47:312523 u32 nBlob;
drh03999942023-11-15 16:10:312524 assert( pParse->delta!=0 );
drhaf0c9ff2023-11-15 18:47:312525 assert( pParse->nBlobAlloc >= pParse->nBlob );
2526 nBlob = pParse->nBlob;
2527 pParse->nBlob = pParse->nBlobAlloc;
drh7b5123c2023-11-03 12:09:222528 (void)jsonbPayloadSize(pParse, iRoot, &sz);
drhaf0c9ff2023-11-15 18:47:312529 pParse->nBlob = nBlob;
drh7b5123c2023-11-03 12:09:222530 sz += pParse->delta;
drhef97f832023-11-28 18:16:022531 pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz);
drh7b5123c2023-11-03 12:09:222532}
2533
2534/*
drh3a7042e2025-04-01 15:17:012535** If the JSONB at aIns[0..nIns-1] can be expanded (by denormalizing the
2536** size field) by d bytes, then write the expansion into aOut[] and
2537** return true. In this way, an overwrite happens without changing the
2538** size of the JSONB, which reduces memcpy() operations and also make it
2539** faster and easier to update the B-Tree entry that contains the JSONB
2540** in the database.
2541**
2542** If the expansion of aIns[] by d bytes cannot be (easily) accomplished
2543** then return false.
2544**
2545** The d parameter is guaranteed to be between 1 and 8.
2546**
2547** This routine is an optimization. A correct answer is obtained if it
2548** always leaves the output unchanged and returns false.
2549*/
2550static int jsonBlobOverwrite(
2551 u8 *aOut, /* Overwrite here */
2552 const u8 *aIns, /* New content */
2553 u32 nIns, /* Bytes of new content */
2554 u32 d /* Need to expand new content by this much */
2555){
2556 u32 szPayload; /* Bytes of payload */
2557 u32 i; /* New header size, after expansion & a loop counter */
2558 u8 szHdr; /* Size of header before expansion */
2559
2560 /* Lookup table for finding the upper 4 bits of the first byte of the
2561 ** expanded aIns[], based on the size of the expanded aIns[] header:
2562 **
2563 ** 2 3 4 5 6 7 8 9 */
2564 static const u8 aType[] = { 0xc0, 0xd0, 0, 0xe0, 0, 0, 0, 0xf0 };
2565
drh76076d42025-04-01 16:26:512566 if( (aIns[0]&0x0f)<=2 ) return 0; /* Cannot enlarge NULL, true, false */
drh3a7042e2025-04-01 15:17:012567 switch( aIns[0]>>4 ){
2568 default: { /* aIns[] header size 1 */
2569 if( ((1<<d)&0x116)==0 ) return 0; /* d must be 1, 2, 4, or 8 */
2570 i = d + 1; /* New hdr sz: 2, 3, 5, or 9 */
2571 szHdr = 1;
2572 break;
2573 }
2574 case 12: { /* aIns[] header size is 2 */
2575 if( ((1<<d)&0x8a)==0) return 0; /* d must be 1, 3, or 7 */
2576 i = d + 2; /* New hdr sz: 2, 5, or 9 */
2577 szHdr = 2;
2578 break;
2579 }
2580 case 13: { /* aIns[] header size is 3 */
2581 if( d!=2 && d!=6 ) return 0; /* d must be 2 or 6 */
2582 i = d + 3; /* New hdr sz: 5 or 9 */
2583 szHdr = 3;
2584 break;
2585 }
2586 case 14: { /* aIns[] header size is 5 */
2587 if( d!=4 ) return 0; /* d must be 4 */
2588 i = 9; /* New hdr sz: 9 */
2589 szHdr = 5;
2590 break;
2591 }
2592 case 15: { /* aIns[] header size is 9 */
2593 return 0; /* No solution */
2594 }
2595 }
2596 assert( i>=2 && i<=9 && aType[i-2]!=0 );
2597 aOut[0] = (aIns[0] & 0x0f) | aType[i-2];
2598 memcpy(&aOut[i], &aIns[szHdr], nIns-szHdr);
2599 szPayload = nIns - szHdr;
2600 while( 1/*edit-by-break*/ ){
2601 i--;
2602 aOut[i] = szPayload & 0xff;
2603 if( i==1 ) break;
2604 szPayload >>= 8;
2605 }
2606 assert( (szPayload>>8)==0 );
2607 return 1;
2608}
2609
2610/*
drheb04a0b2023-11-27 23:46:122611** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of
2612** content beginning at iDel, and replacing them with nIns bytes of
2613** content given by aIns.
2614**
2615** nDel may be zero, in which case no bytes are removed. But iDel is
2616** still important as new bytes will be insert beginning at iDel.
2617**
drhf46f89d2023-11-28 00:27:582618** aIns may be zero, in which case space is created to hold nIns bytes
2619** beginning at iDel, but that space is uninitialized.
drheb04a0b2023-11-27 23:46:122620**
2621** Set pParse->oom if an OOM occurs.
2622*/
2623static void jsonBlobEdit(
2624 JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */
2625 u32 iDel, /* First byte to be removed */
2626 u32 nDel, /* Number of bytes to remove */
2627 const u8 *aIns, /* Content to insert */
2628 u32 nIns /* Bytes of content to insert */
2629){
2630 i64 d = (i64)nIns - (i64)nDel;
drh3a7042e2025-04-01 15:17:012631 if( d<0 && d>=(-8) && aIns!=0
2632 && jsonBlobOverwrite(&pParse->aBlob[iDel], aIns, nIns, (int)-d)
2633 ){
2634 return;
2635 }
drheb04a0b2023-11-27 23:46:122636 if( d!=0 ){
2637 if( pParse->nBlob + d > pParse->nBlobAlloc ){
2638 jsonBlobExpand(pParse, pParse->nBlob+d);
2639 if( pParse->oom ) return;
2640 }
2641 memmove(&pParse->aBlob[iDel+nIns],
2642 &pParse->aBlob[iDel+nDel],
2643 pParse->nBlob - (iDel+nDel));
2644 pParse->nBlob += d;
2645 pParse->delta += d;
2646 }
drh3a7042e2025-04-01 15:17:012647 if( nIns && aIns ){
2648 memcpy(&pParse->aBlob[iDel], aIns, nIns);
2649 }
drheb04a0b2023-11-27 23:46:122650}
2651
2652/*
drh91ec00c2023-12-06 14:50:482653** Return the number of escaped newlines to be ignored.
2654** An escaped newline is a one of the following byte sequences:
2655**
2656** 0x5c 0x0a
2657** 0x5c 0x0d
2658** 0x5c 0x0d 0x0a
2659** 0x5c 0xe2 0x80 0xa8
2660** 0x5c 0xe2 0x80 0xa9
2661*/
2662static u32 jsonBytesToBypass(const char *z, u32 n){
2663 u32 i = 0;
2664 while( i+1<n ){
2665 if( z[i]!='\\' ) return i;
2666 if( z[i+1]=='\n' ){
2667 i += 2;
2668 continue;
2669 }
2670 if( z[i+1]=='\r' ){
2671 if( i+2<n && z[i+2]=='\n' ){
2672 i += 3;
2673 }else{
2674 i += 2;
2675 }
2676 continue;
2677 }
2678 if( 0xe2==(u8)z[i+1]
2679 && i+3<n
2680 && 0x80==(u8)z[i+2]
2681 && (0xa8==(u8)z[i+3] || 0xa9==(u8)z[i+3])
2682 ){
2683 i += 4;
2684 continue;
2685 }
2686 break;
2687 }
2688 return i;
2689}
2690
2691/*
2692** Input z[0..n] defines JSON escape sequence including the leading '\\'.
2693** Decode that escape sequence into a single character. Write that
2694** character into *piOut. Return the number of bytes in the escape sequence.
drhb2b74902023-12-26 13:20:572695**
2696** If there is a syntax error of some kind (for example too few characters
2697** after the '\\' to complete the encoding) then *piOut is set to
2698** JSON_INVALID_CHAR.
drh91ec00c2023-12-06 14:50:482699*/
2700static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){
2701 assert( n>0 );
2702 assert( z[0]=='\\' );
2703 if( n<2 ){
drhb2b74902023-12-26 13:20:572704 *piOut = JSON_INVALID_CHAR;
drh91ec00c2023-12-06 14:50:482705 return n;
2706 }
2707 switch( (u8)z[1] ){
2708 case 'u': {
2709 u32 v, vlo;
2710 if( n<6 ){
drhb2b74902023-12-26 13:20:572711 *piOut = JSON_INVALID_CHAR;
drh91ec00c2023-12-06 14:50:482712 return n;
2713 }
2714 v = jsonHexToInt4(&z[2]);
2715 if( (v & 0xfc00)==0xd800
2716 && n>=12
2717 && z[6]=='\\'
2718 && z[7]=='u'
2719 && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00
2720 ){
2721 *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000;
2722 return 12;
2723 }else{
2724 *piOut = v;
2725 return 6;
2726 }
2727 }
2728 case 'b': { *piOut = '\b'; return 2; }
2729 case 'f': { *piOut = '\f'; return 2; }
2730 case 'n': { *piOut = '\n'; return 2; }
2731 case 'r': { *piOut = '\r'; return 2; }
2732 case 't': { *piOut = '\t'; return 2; }
2733 case 'v': { *piOut = '\v'; return 2; }
drh844b4572025-05-10 15:53:172734 case '0': {
drh94e22bc2025-05-10 17:09:532735 /* JSON5 requires that the \0 escape not be followed by a digit.
2736 ** But SQLite did not enforce this restriction in versions 3.42.0
2737 ** through 3.49.2. That was a bug. But some applications might have
2738 ** come to depend on that bug. Use the SQLITE_BUG_COMPATIBLE_20250510
2739 ** option to restore the old buggy behavior. */
2740#ifdef SQLITE_BUG_COMPATIBLE_20250510
2741 /* Legacy bug-compatible behavior */
2742 *piOut = 0;
2743#else
2744 /* Correct behavior */
drh844b4572025-05-10 15:53:172745 *piOut = (n>2 && sqlite3Isdigit(z[2])) ? JSON_INVALID_CHAR : 0;
drh94e22bc2025-05-10 17:09:532746#endif
drh844b4572025-05-10 15:53:172747 return 2;
2748 }
drh91ec00c2023-12-06 14:50:482749 case '\'':
2750 case '"':
2751 case '/':
2752 case '\\':{ *piOut = z[1]; return 2; }
2753 case 'x': {
2754 if( n<4 ){
drhb2b74902023-12-26 13:20:572755 *piOut = JSON_INVALID_CHAR;
drh91ec00c2023-12-06 14:50:482756 return n;
2757 }
2758 *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]);
2759 return 4;
2760 }
2761 case 0xe2:
2762 case '\r':
2763 case '\n': {
2764 u32 nSkip = jsonBytesToBypass(z, n);
2765 if( nSkip==0 ){
drhb2b74902023-12-26 13:20:572766 *piOut = JSON_INVALID_CHAR;
drh91ec00c2023-12-06 14:50:482767 return n;
2768 }else if( nSkip==n ){
2769 *piOut = 0;
2770 return n;
2771 }else if( z[nSkip]=='\\' ){
2772 return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut);
2773 }else{
drh001d1e72023-12-13 14:31:152774 int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut);
2775 return nSkip + sz;
drh91ec00c2023-12-06 14:50:482776 }
2777 }
2778 default: {
drhb2b74902023-12-26 13:20:572779 *piOut = JSON_INVALID_CHAR;
drh91ec00c2023-12-06 14:50:482780 return 2;
2781 }
2782 }
2783}
2784
2785
2786/*
2787** Compare two object labels. Return 1 if they are equal and
2788** 0 if they differ.
2789**
2790** In this version, we know that one or the other or both of the
2791** two comparands contains an escape sequence.
2792*/
2793static SQLITE_NOINLINE int jsonLabelCompareEscaped(
2794 const char *zLeft, /* The left label */
2795 u32 nLeft, /* Size of the left label in bytes */
2796 int rawLeft, /* True if zLeft contains no escapes */
2797 const char *zRight, /* The right label */
2798 u32 nRight, /* Size of the right label in bytes */
2799 int rawRight /* True if zRight is escape-free */
2800){
2801 u32 cLeft, cRight;
2802 assert( rawLeft==0 || rawRight==0 );
drh891f1dc2023-12-12 18:38:532803 while( 1 /*exit-by-return*/ ){
2804 if( nLeft==0 ){
2805 cLeft = 0;
2806 }else if( rawLeft || zLeft[0]!='\\' ){
drh91ec00c2023-12-06 14:50:482807 cLeft = ((u8*)zLeft)[0];
drh001d1e72023-12-13 14:31:152808 if( cLeft>=0xc0 ){
2809 int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft);
2810 zLeft += sz;
2811 nLeft -= sz;
2812 }else{
2813 zLeft++;
2814 nLeft--;
2815 }
drh91ec00c2023-12-06 14:50:482816 }else{
2817 u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft);
2818 zLeft += n;
2819 assert( n<=nLeft );
2820 nLeft -= n;
2821 }
drh891f1dc2023-12-12 18:38:532822 if( nRight==0 ){
2823 cRight = 0;
2824 }else if( rawRight || zRight[0]!='\\' ){
drh91ec00c2023-12-06 14:50:482825 cRight = ((u8*)zRight)[0];
drh001d1e72023-12-13 14:31:152826 if( cRight>=0xc0 ){
2827 int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight);
2828 zRight += sz;
2829 nRight -= sz;
2830 }else{
2831 zRight++;
2832 nRight--;
2833 }
drh91ec00c2023-12-06 14:50:482834 }else{
2835 u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight);
2836 zRight += n;
2837 assert( n<=nRight );
2838 nRight -= n;
2839 }
2840 if( cLeft!=cRight ) return 0;
drh891f1dc2023-12-12 18:38:532841 if( cLeft==0 ) return 1;
drh91ec00c2023-12-06 14:50:482842 }
drh91ec00c2023-12-06 14:50:482843}
2844
2845/*
2846** Compare two object labels. Return 1 if they are equal and
2847** 0 if they differ. Return -1 if an OOM occurs.
2848*/
2849static int jsonLabelCompare(
2850 const char *zLeft, /* The left label */
2851 u32 nLeft, /* Size of the left label in bytes */
2852 int rawLeft, /* True if zLeft contains no escapes */
2853 const char *zRight, /* The right label */
2854 u32 nRight, /* Size of the right label in bytes */
2855 int rawRight /* True if zRight is escape-free */
2856){
2857 if( rawLeft && rawRight ){
2858 /* Simpliest case: Neither label contains escapes. A simple
2859 ** memcmp() is sufficient. */
2860 if( nLeft!=nRight ) return 0;
2861 return memcmp(zLeft, zRight, nLeft)==0;
2862 }else{
2863 return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft,
2864 zRight, nRight, rawRight);
2865 }
2866}
2867
2868/*
drh53c21602023-12-02 18:17:382869** Error returns from jsonLookupStep()
drh18548372023-09-28 10:20:562870*/
drh53c21602023-12-02 18:17:382871#define JSON_LOOKUP_ERROR 0xffffffff
2872#define JSON_LOOKUP_NOTFOUND 0xfffffffe
2873#define JSON_LOOKUP_PATHERROR 0xfffffffd
2874#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR)
drh18548372023-09-28 10:20:562875
drhc1e85742023-12-02 20:25:362876/* Forward declaration */
2877static u32 jsonLookupStep(JsonParse*,u32,const char*,u32);
2878
2879
2880/* This helper routine for jsonLookupStep() populates pIns with
2881** binary data that is to be inserted into pParse.
2882**
2883** In the common case, pIns just points to pParse->aIns and pParse->nIns.
2884** But if the zPath of the original edit operation includes path elements
2885** that go deeper, additional substructure must be created.
2886**
2887** For example:
2888**
2889** json_insert('{}', '$.a.b.c', 123);
2890**
2891** The search stops at '$.a' But additional substructure must be
2892** created for the ".b.c" part of the patch so that the final result
2893** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with
2894** the binary equivalent of {"b":{"c":123}} so that it can be inserted.
2895**
2896** The caller is responsible for resetting pIns when it has finished
2897** using the substructure.
2898*/
2899static u32 jsonCreateEditSubstructure(
2900 JsonParse *pParse, /* The original JSONB that is being edited */
2901 JsonParse *pIns, /* Populate this with the blob data to insert */
2902 const char *zTail /* Tail of the path that determins substructure */
2903){
2904 static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT };
2905 int rc;
2906 memset(pIns, 0, sizeof(*pIns));
drh4093b292024-01-03 16:41:502907 pIns->db = pParse->db;
drhc1e85742023-12-02 20:25:362908 if( zTail[0]==0 ){
2909 /* No substructure. Just insert what is given in pParse. */
2910 pIns->aBlob = pParse->aIns;
2911 pIns->nBlob = pParse->nIns;
2912 rc = 0;
2913 }else{
2914 /* Construct the binary substructure */
2915 pIns->nBlob = 1;
2916 pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.'];
2917 pIns->eEdit = pParse->eEdit;
2918 pIns->nIns = pParse->nIns;
2919 pIns->aIns = pParse->aIns;
2920 rc = jsonLookupStep(pIns, 0, zTail, 0);
2921 pParse->oom |= pIns->oom;
2922 }
2923 return rc; /* Error code only */
2924}
2925
drh18548372023-09-28 10:20:562926/*
2927** Search along zPath to find the Json element specified. Return an
2928** index into pParse->aBlob[] for the start of that element's value.
2929**
drh53c21602023-12-02 18:17:382930** If the value found by this routine is the value half of label/value pair
2931** within an object, then set pPath->iLabel to the start of the corresponding
2932** label, before returning.
2933**
2934** Return one of the JSON_LOOKUP error codes if problems are seen.
drhc1e85742023-12-02 20:25:362935**
2936** This routine will also modify the blob. If pParse->eEdit is one of
2937** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be
2938** made to the selected value. If an edit is performed, then the return
2939** value does not necessarily point to the select element. If an edit
2940** is performed, the return value is only useful for detecting error
2941** conditions.
drh18548372023-09-28 10:20:562942*/
drh53c21602023-12-02 18:17:382943static u32 jsonLookupStep(
drh18548372023-09-28 10:20:562944 JsonParse *pParse, /* The JSON to search */
2945 u32 iRoot, /* Begin the search at this element of aBlob[] */
drh03999942023-11-15 16:10:312946 const char *zPath, /* The path to search */
2947 u32 iLabel /* Label if iRoot is a value of in an object */
drh18548372023-09-28 10:20:562948){
drh7b5123c2023-11-03 12:09:222949 u32 i, j, k, nKey, sz, n, iEnd, rc;
drh18548372023-09-28 10:20:562950 const char *zKey;
2951 u8 x;
2952
drh7b5123c2023-11-03 12:09:222953 if( zPath[0]==0 ){
drh5026ddb2023-11-28 12:28:282954 if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){
drh7b5123c2023-11-03 12:09:222955 n = jsonbPayloadSize(pParse, iRoot, &sz);
2956 sz += n;
2957 if( pParse->eEdit==JEDIT_DEL ){
drh03999942023-11-15 16:10:312958 if( iLabel>0 ){
2959 sz += iRoot - iLabel;
2960 iRoot = iLabel;
2961 }
drheb04a0b2023-11-27 23:46:122962 jsonBlobEdit(pParse, iRoot, sz, 0, 0);
drh7b5123c2023-11-03 12:09:222963 }else if( pParse->eEdit==JEDIT_INS ){
2964 /* Already exists, so json_insert() is a no-op */
2965 }else{
2966 /* json_set() or json_replace() */
drheb04a0b2023-11-27 23:46:122967 jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns);
drh7b5123c2023-11-03 12:09:222968 }
2969 }
drhb7d5cb72023-11-25 13:40:192970 pParse->iLabel = iLabel;
drh7b5123c2023-11-03 12:09:222971 return iRoot;
2972 }
drh18548372023-09-28 10:20:562973 if( zPath[0]=='.' ){
drh91ec00c2023-12-06 14:50:482974 int rawKey = 1;
drh18548372023-09-28 10:20:562975 x = pParse->aBlob[iRoot];
drh18548372023-09-28 10:20:562976 zPath++;
2977 if( zPath[0]=='"' ){
2978 zKey = zPath + 1;
drhbb4d2ed2024-09-04 16:01:442979 for(i=1; zPath[i] && zPath[i]!='"'; i++){
2980 if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++;
2981 }
drh18548372023-09-28 10:20:562982 nKey = i-1;
2983 if( zPath[i] ){
2984 i++;
2985 }else{
drh53c21602023-12-02 18:17:382986 return JSON_LOOKUP_PATHERROR;
drh18548372023-09-28 10:20:562987 }
2988 testcase( nKey==0 );
drh91ec00c2023-12-06 14:50:482989 rawKey = memchr(zKey, '\\', nKey)==0;
drh18548372023-09-28 10:20:562990 }else{
2991 zKey = zPath;
2992 for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
2993 nKey = i;
2994 if( nKey==0 ){
drh53c21602023-12-02 18:17:382995 return JSON_LOOKUP_PATHERROR;
drh18548372023-09-28 10:20:562996 }
2997 }
drh53c21602023-12-02 18:17:382998 if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND;
drh18548372023-09-28 10:20:562999 n = jsonbPayloadSize(pParse, iRoot, &sz);
drh03999942023-11-15 16:10:313000 j = iRoot + n; /* j is the index of a label */
drh18548372023-09-28 10:20:563001 iEnd = j+sz;
3002 while( j<iEnd ){
drh91ec00c2023-12-06 14:50:483003 int rawLabel;
3004 const char *zLabel;
drh18548372023-09-28 10:20:563005 x = pParse->aBlob[j] & 0x0f;
drh53c21602023-12-02 18:17:383006 if( x<JSONB_TEXT || x>JSONB_TEXTRAW ) return JSON_LOOKUP_ERROR;
drh18548372023-09-28 10:20:563007 n = jsonbPayloadSize(pParse, j, &sz);
drh53c21602023-12-02 18:17:383008 if( n==0 ) return JSON_LOOKUP_ERROR;
drh03999942023-11-15 16:10:313009 k = j+n; /* k is the index of the label text */
drh53c21602023-12-02 18:17:383010 if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR;
drh91ec00c2023-12-06 14:50:483011 zLabel = (const char*)&pParse->aBlob[k];
3012 rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW;
3013 if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){
drh03999942023-11-15 16:10:313014 u32 v = k+sz; /* v is the index of the value */
drh53c21602023-12-02 18:17:383015 if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR;
drh03999942023-11-15 16:10:313016 n = jsonbPayloadSize(pParse, v, &sz);
drh53c21602023-12-02 18:17:383017 if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR;
drh03999942023-11-15 16:10:313018 assert( j>0 );
drh53c21602023-12-02 18:17:383019 rc = jsonLookupStep(pParse, v, &zPath[i], j);
drh7b5123c2023-11-03 12:09:223020 if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
3021 return rc;
drh18548372023-09-28 10:20:563022 }
3023 j = k+sz;
drh53c21602023-12-02 18:17:383024 if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR;
drh18548372023-09-28 10:20:563025 n = jsonbPayloadSize(pParse, j, &sz);
drh53c21602023-12-02 18:17:383026 if( n==0 ) return JSON_LOOKUP_ERROR;
drh18548372023-09-28 10:20:563027 j += n+sz;
3028 }
drh53c21602023-12-02 18:17:383029 if( j>iEnd ) return JSON_LOOKUP_ERROR;
drh27fea972023-11-21 20:13:083030 if( pParse->eEdit>=JEDIT_INS ){
drh66795962023-11-30 19:06:273031 u32 nIns; /* Total bytes to insert (label+value) */
3032 JsonParse v; /* BLOB encoding of the value to be inserted */
3033 JsonParse ix; /* Header of the label to be inserted */
drh27fea972023-11-21 20:13:083034 testcase( pParse->eEdit==JEDIT_INS );
3035 testcase( pParse->eEdit==JEDIT_SET );
3036 memset(&ix, 0, sizeof(ix));
drh4093b292024-01-03 16:41:503037 ix.db = pParse->db;
drh91ec00c2023-12-06 14:50:483038 jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0);
drh5ec9c912023-12-02 01:06:333039 pParse->oom |= ix.oom;
drhc1e85742023-12-02 20:25:363040 rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]);
3041 if( !JSON_LOOKUP_ISERROR(rc)
3042 && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob)
3043 ){
3044 assert( !pParse->oom );
drh66795962023-11-30 19:06:273045 nIns = ix.nBlob + nKey + v.nBlob;
drhf46f89d2023-11-28 00:27:583046 jsonBlobEdit(pParse, j, 0, 0, nIns);
drh99c41692023-12-04 16:01:393047 if( !pParse->oom ){
drh5afd67b2023-12-05 19:24:073048 assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */
3049 assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */
drh05db5132023-12-02 16:11:223050 memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob);
3051 k = j + ix.nBlob;
3052 memcpy(&pParse->aBlob[k], zKey, nKey);
3053 k += nKey;
3054 memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob);
drhdc138cb2023-12-04 13:12:453055 if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot);
drh05db5132023-12-02 16:11:223056 }
drh27fea972023-11-21 20:13:083057 }
drh66795962023-11-30 19:06:273058 jsonParseReset(&v);
drh5ec9c912023-12-02 01:06:333059 jsonParseReset(&ix);
drhc1e85742023-12-02 20:25:363060 return rc;
drh27fea972023-11-21 20:13:083061 }
drh18548372023-09-28 10:20:563062 }else if( zPath[0]=='[' ){
drh6b1db922023-09-28 17:23:463063 x = pParse->aBlob[iRoot] & 0x0f;
drh53c21602023-12-02 18:17:383064 if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND;
drh6b1db922023-09-28 17:23:463065 n = jsonbPayloadSize(pParse, iRoot, &sz);
drh18548372023-09-28 10:20:563066 k = 0;
3067 i = 1;
3068 while( sqlite3Isdigit(zPath[i]) ){
3069 k = k*10 + zPath[i] - '0';
3070 i++;
3071 }
3072 if( i<2 || zPath[i]!=']' ){
drh18548372023-09-28 10:20:563073 if( zPath[1]=='#' ){
drh6b1db922023-09-28 17:23:463074 k = jsonbArrayCount(pParse, iRoot);
3075 i = 2;
drh18548372023-09-28 10:20:563076 if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){
drhe690d5a2023-10-06 14:59:403077 unsigned int nn = 0;
drh6b1db922023-09-28 17:23:463078 i = 3;
drh18548372023-09-28 10:20:563079 do{
drhe690d5a2023-10-06 14:59:403080 nn = nn*10 + zPath[i] - '0';
drh6b1db922023-09-28 17:23:463081 i++;
3082 }while( sqlite3Isdigit(zPath[i]) );
drh53c21602023-12-02 18:17:383083 if( nn>k ) return JSON_LOOKUP_NOTFOUND;
drhe690d5a2023-10-06 14:59:403084 k -= nn;
drh18548372023-09-28 10:20:563085 }
drh6b1db922023-09-28 17:23:463086 if( zPath[i]!=']' ){
drh53c21602023-12-02 18:17:383087 return JSON_LOOKUP_PATHERROR;
drh18548372023-09-28 10:20:563088 }
3089 }else{
drh53c21602023-12-02 18:17:383090 return JSON_LOOKUP_PATHERROR;
drh18548372023-09-28 10:20:563091 }
drh18548372023-09-28 10:20:563092 }
drh18548372023-09-28 10:20:563093 j = iRoot+n;
3094 iEnd = j+sz;
3095 while( j<iEnd ){
3096 if( k==0 ){
drh53c21602023-12-02 18:17:383097 rc = jsonLookupStep(pParse, j, &zPath[i+1], 0);
drh7b5123c2023-11-03 12:09:223098 if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
3099 return rc;
drh18548372023-09-28 10:20:563100 }
3101 k--;
3102 n = jsonbPayloadSize(pParse, j, &sz);
drh53c21602023-12-02 18:17:383103 if( n==0 ) return JSON_LOOKUP_ERROR;
drh18548372023-09-28 10:20:563104 j += n+sz;
3105 }
drh53c21602023-12-02 18:17:383106 if( j>iEnd ) return JSON_LOOKUP_ERROR;
3107 if( k>0 ) return JSON_LOOKUP_NOTFOUND;
drh66795962023-11-30 19:06:273108 if( pParse->eEdit>=JEDIT_INS ){
3109 JsonParse v;
drh27fea972023-11-21 20:13:083110 testcase( pParse->eEdit==JEDIT_INS );
3111 testcase( pParse->eEdit==JEDIT_SET );
drhc1e85742023-12-02 20:25:363112 rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]);
3113 if( !JSON_LOOKUP_ISERROR(rc)
3114 && jsonBlobMakeEditable(pParse, v.nBlob)
3115 ){
3116 assert( !pParse->oom );
drh66795962023-11-30 19:06:273117 jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob);
3118 }
3119 jsonParseReset(&v);
drhbfc7e622023-11-30 00:52:333120 if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot);
drhc1e85742023-12-02 20:25:363121 return rc;
drh27fea972023-11-21 20:13:083122 }
drh18548372023-09-28 10:20:563123 }else{
drh53c21602023-12-02 18:17:383124 return JSON_LOOKUP_PATHERROR;
drh18548372023-09-28 10:20:563125 }
drh53c21602023-12-02 18:17:383126 return JSON_LOOKUP_NOTFOUND;
drh18548372023-09-28 10:20:563127}
3128
3129/*
drh2dc60ec2023-09-28 15:56:353130** Convert a JSON BLOB into text and make that text the return value
3131** of an SQL function.
3132*/
3133static void jsonReturnTextJsonFromBlob(
3134 sqlite3_context *ctx,
3135 const u8 *aBlob,
3136 u32 nBlob
3137){
3138 JsonParse x;
3139 JsonString s;
3140
drhdc138cb2023-12-04 13:12:453141 if( NEVER(aBlob==0) ) return;
drh2dc60ec2023-09-28 15:56:353142 memset(&x, 0, sizeof(x));
3143 x.aBlob = (u8*)aBlob;
3144 x.nBlob = nBlob;
drhae5f55e2023-09-29 12:45:143145 jsonStringInit(&s, ctx);
drh3262ca82023-12-19 21:39:583146 jsonTranslateBlobToText(&x, 0, &s);
drhca1ce772023-12-01 12:57:123147 jsonReturnString(&s, 0, 0);
drh2dc60ec2023-09-28 15:56:353148}
3149
3150
3151/*
3152** Return the value of the BLOB node at index i.
3153**
3154** If the value is a primitive, return it as an SQL value.
3155** If the value is an array or object, return it as either
3156** JSON text or the BLOB encoding, depending on the JSON_B flag
3157** on the userdata.
drh18548372023-09-28 10:20:563158*/
3159static void jsonReturnFromBlob(
3160 JsonParse *pParse, /* Complete JSON parse tree */
3161 u32 i, /* Index of the node */
drhabbdbdf2023-11-24 18:44:003162 sqlite3_context *pCtx, /* Return value for this function */
3163 int textOnly /* return text JSON. Disregard user-data */
drh18548372023-09-28 10:20:563164){
3165 u32 n, sz;
3166 int rc;
3167 sqlite3 *db = sqlite3_context_db_handle(pCtx);
3168
3169 n = jsonbPayloadSize(pParse, i, &sz);
drh3fedb7e2023-12-04 18:53:103170 if( n==0 ){
3171 sqlite3_result_error(pCtx, "malformed JSON", -1);
3172 return;
3173 }
drh18548372023-09-28 10:20:563174 switch( pParse->aBlob[i] & 0x0f ){
3175 case JSONB_NULL: {
drh5b6b7032023-12-07 12:55:393176 if( sz ) goto returnfromblob_malformed;
drh18548372023-09-28 10:20:563177 sqlite3_result_null(pCtx);
3178 break;
3179 }
3180 case JSONB_TRUE: {
drh5b6b7032023-12-07 12:55:393181 if( sz ) goto returnfromblob_malformed;
drh18548372023-09-28 10:20:563182 sqlite3_result_int(pCtx, 1);
3183 break;
3184 }
3185 case JSONB_FALSE: {
drh5b6b7032023-12-07 12:55:393186 if( sz ) goto returnfromblob_malformed;
drh18548372023-09-28 10:20:563187 sqlite3_result_int(pCtx, 0);
3188 break;
3189 }
3190 case JSONB_INT5:
3191 case JSONB_INT: {
3192 sqlite3_int64 iRes = 0;
3193 char *z;
3194 int bNeg = 0;
drh5b6b7032023-12-07 12:55:393195 char x;
3196 if( sz==0 ) goto returnfromblob_malformed;
3197 x = (char)pParse->aBlob[i+n];
3198 if( x=='-' ){
3199 if( sz<2 ) goto returnfromblob_malformed;
3200 n++;
3201 sz--;
3202 bNeg = 1;
3203 }
drh18548372023-09-28 10:20:563204 z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
drh5b6b7032023-12-07 12:55:393205 if( z==0 ) goto returnfromblob_oom;
drh18548372023-09-28 10:20:563206 rc = sqlite3DecOrHexToI64(z, &iRes);
3207 sqlite3DbFree(db, z);
drh5b6b7032023-12-07 12:55:393208 if( rc==0 ){
drh18548372023-09-28 10:20:563209 sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes);
3210 }else if( rc==3 && bNeg ){
3211 sqlite3_result_int64(pCtx, SMALLEST_INT64);
drh5b6b7032023-12-07 12:55:393212 }else if( rc==1 ){
3213 goto returnfromblob_malformed;
drh18548372023-09-28 10:20:563214 }else{
drhf3627312023-10-03 21:54:093215 if( bNeg ){ n--; sz++; }
drh18548372023-09-28 10:20:563216 goto to_double;
3217 }
3218 break;
3219 }
3220 case JSONB_FLOAT5:
3221 case JSONB_FLOAT: {
3222 double r;
3223 char *z;
drh5b6b7032023-12-07 12:55:393224 if( sz==0 ) goto returnfromblob_malformed;
drh18548372023-09-28 10:20:563225 to_double:
3226 z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
drh5b6b7032023-12-07 12:55:393227 if( z==0 ) goto returnfromblob_oom;
3228 rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
drh18548372023-09-28 10:20:563229 sqlite3DbFree(db, z);
drh5b6b7032023-12-07 12:55:393230 if( rc<=0 ) goto returnfromblob_malformed;
drh18548372023-09-28 10:20:563231 sqlite3_result_double(pCtx, r);
3232 break;
3233 }
3234 case JSONB_TEXTRAW:
3235 case JSONB_TEXT: {
3236 sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz,
3237 SQLITE_TRANSIENT);
3238 break;
3239 }
3240 case JSONB_TEXT5:
3241 case JSONB_TEXTJ: {
3242 /* Translate JSON formatted string into raw text */
3243 u32 iIn, iOut;
3244 const char *z;
3245 char *zOut;
3246 u32 nOut = sz;
3247 z = (const char*)&pParse->aBlob[i+n];
drh7bfa4452025-02-17 18:09:243248 zOut = sqlite3DbMallocRaw(db, ((u64)nOut)+1);
drh5b6b7032023-12-07 12:55:393249 if( zOut==0 ) goto returnfromblob_oom;
drh18548372023-09-28 10:20:563250 for(iIn=iOut=0; iIn<sz; iIn++){
3251 char c = z[iIn];
3252 if( c=='\\' ){
drh91ec00c2023-12-06 14:50:483253 u32 v;
3254 u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v);
3255 if( v<=0x7f ){
3256 zOut[iOut++] = (char)v;
3257 }else if( v<=0x7ff ){
drh001d1e72023-12-13 14:31:153258 assert( szEscape>=2 );
drh91ec00c2023-12-06 14:50:483259 zOut[iOut++] = (char)(0xc0 | (v>>6));
3260 zOut[iOut++] = 0x80 | (v&0x3f);
3261 }else if( v<0x10000 ){
drh001d1e72023-12-13 14:31:153262 assert( szEscape>=3 );
drh91ec00c2023-12-06 14:50:483263 zOut[iOut++] = 0xe0 | (v>>12);
3264 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
3265 zOut[iOut++] = 0x80 | (v&0x3f);
drhb2b74902023-12-26 13:20:573266 }else if( v==JSON_INVALID_CHAR ){
3267 /* Silently ignore illegal unicode */
drh18548372023-09-28 10:20:563268 }else{
drh001d1e72023-12-13 14:31:153269 assert( szEscape>=4 );
drh91ec00c2023-12-06 14:50:483270 zOut[iOut++] = 0xf0 | (v>>18);
3271 zOut[iOut++] = 0x80 | ((v>>12)&0x3f);
3272 zOut[iOut++] = 0x80 | ((v>>6)&0x3f);
3273 zOut[iOut++] = 0x80 | (v&0x3f);
drh18548372023-09-28 10:20:563274 }
drh91ec00c2023-12-06 14:50:483275 iIn += szEscape - 1;
3276 }else{
3277 zOut[iOut++] = c;
3278 }
drh18548372023-09-28 10:20:563279 } /* end for() */
drh001d1e72023-12-13 14:31:153280 assert( iOut<=nOut );
drh18548372023-09-28 10:20:563281 zOut[iOut] = 0;
drh4093b292024-01-03 16:41:503282 sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
drh18548372023-09-28 10:20:563283 break;
3284 }
3285 case JSONB_ARRAY:
3286 case JSONB_OBJECT: {
drhabbdbdf2023-11-24 18:44:003287 int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx));
drh2dc60ec2023-09-28 15:56:353288 if( flags & JSON_BLOB ){
3289 sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
3290 }else{
3291 jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
3292 }
drh18548372023-09-28 10:20:563293 break;
3294 }
drha7e93862023-10-07 23:35:073295 default: {
drh5b6b7032023-12-07 12:55:393296 goto returnfromblob_malformed;
drha7e93862023-10-07 23:35:073297 }
drh18548372023-09-28 10:20:563298 }
drh5b6b7032023-12-07 12:55:393299 return;
3300
3301returnfromblob_oom:
3302 sqlite3_result_error_nomem(pCtx);
3303 return;
3304
3305returnfromblob_malformed:
3306 sqlite3_result_error(pCtx, "malformed JSON", -1);
3307 return;
drh18548372023-09-28 10:20:563308}
3309
drh8a4ceca2023-11-21 17:51:583310/*
3311** pArg is a function argument that might be an SQL value or a JSON
3312** value. Figure out what it is and encode it as a JSONB blob.
3313** Return the results in pParse.
3314**
3315** pParse is uninitialized upon entry. This routine will handle the
3316** initialization of pParse. The result will be contained in
3317** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically
3318** allocated (if pParse->nBlobAlloc is greater than zero) in which case
3319** the caller is responsible for freeing the space allocated to pParse->aBlob
3320** when it has finished with it. Or pParse->aBlob might be a static string
3321** or a value obtained from sqlite3_value_blob(pArg).
3322**
3323** If the argument is a BLOB that is clearly not a JSONB, then this
3324** function might set an error message in ctx and return non-zero.
3325** It might also set an error message and return non-zero on an OOM error.
3326*/
3327static int jsonFunctionArgToBlob(
3328 sqlite3_context *ctx,
3329 sqlite3_value *pArg,
3330 JsonParse *pParse
3331){
3332 int eType = sqlite3_value_type(pArg);
3333 static u8 aNull[] = { 0x00 };
3334 memset(pParse, 0, sizeof(pParse[0]));
drh4093b292024-01-03 16:41:503335 pParse->db = sqlite3_context_db_handle(ctx);
drh8a4ceca2023-11-21 17:51:583336 switch( eType ){
drhdc138cb2023-12-04 13:12:453337 default: {
drh8a4ceca2023-11-21 17:51:583338 pParse->aBlob = aNull;
3339 pParse->nBlob = 1;
3340 return 0;
3341 }
3342 case SQLITE_BLOB: {
drhcbe4a262025-04-21 19:53:123343 if( !jsonArgIsJsonb(pArg, pParse) ){
drh8a4ceca2023-11-21 17:51:583344 sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1);
3345 return 1;
3346 }
3347 break;
3348 }
3349 case SQLITE_TEXT: {
3350 const char *zJson = (const char*)sqlite3_value_text(pArg);
3351 int nJson = sqlite3_value_bytes(pArg);
3352 if( zJson==0 ) return 1;
3353 if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){
3354 pParse->zJson = (char*)zJson;
3355 pParse->nJson = nJson;
3356 if( jsonConvertTextToBlob(pParse, ctx) ){
3357 sqlite3_result_error(ctx, "malformed JSON", -1);
drh4093b292024-01-03 16:41:503358 sqlite3DbFree(pParse->db, pParse->aBlob);
drh8a4ceca2023-11-21 17:51:583359 memset(pParse, 0, sizeof(pParse[0]));
3360 return 1;
3361 }
3362 }else{
drh679c9082023-12-02 13:36:523363 jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson);
drh8a4ceca2023-11-21 17:51:583364 }
3365 break;
3366 }
drhfc767502023-12-18 18:31:273367 case SQLITE_FLOAT: {
3368 double r = sqlite3_value_double(pArg);
drhc4dd6b42023-12-18 18:50:473369 if( NEVER(sqlite3IsNaN(r)) ){
drhfc767502023-12-18 18:31:273370 jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0);
3371 }else{
3372 int n = sqlite3_value_bytes(pArg);
3373 const char *z = (const char*)sqlite3_value_text(pArg);
3374 if( z==0 ) return 1;
3375 if( z[0]=='I' ){
3376 jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999");
3377 }else if( z[0]=='-' && z[1]=='I' ){
3378 jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999");
3379 }else{
3380 jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z);
3381 }
3382 }
3383 break;
3384 }
drh8a4ceca2023-11-21 17:51:583385 case SQLITE_INTEGER: {
3386 int n = sqlite3_value_bytes(pArg);
3387 const char *z = (const char*)sqlite3_value_text(pArg);
drh8a4ceca2023-11-21 17:51:583388 if( z==0 ) return 1;
drhfc767502023-12-18 18:31:273389 jsonBlobAppendNode(pParse, JSONB_INT, n, z);
drh8a4ceca2023-11-21 17:51:583390 break;
3391 }
3392 }
drhbfc7e622023-11-30 00:52:333393 if( pParse->oom ){
3394 sqlite3_result_error_nomem(ctx);
3395 return 1;
3396 }else{
3397 return 0;
3398 }
drh8a4ceca2023-11-21 17:51:583399}
drhbfc7e622023-11-30 00:52:333400
3401/*
drhca1ce772023-12-01 12:57:123402** Generate a bad path error.
drheb18ae32023-12-03 00:51:303403**
3404** If ctx is not NULL then push the error message into ctx and return NULL.
3405** If ctx is NULL, then return the text of the error message.
drhbfc7e622023-11-30 00:52:333406*/
drheb18ae32023-12-03 00:51:303407static char *jsonBadPathError(
drhbfc7e622023-11-30 00:52:333408 sqlite3_context *ctx, /* The function call containing the error */
3409 const char *zPath /* The path with the problem */
3410){
drheb18ae32023-12-03 00:51:303411 char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath);
3412 if( ctx==0 ) return zMsg;
drha3bf0772023-12-03 20:11:353413 if( zMsg ){
3414 sqlite3_result_error(ctx, zMsg, -1);
3415 sqlite3_free(zMsg);
3416 }else{
3417 sqlite3_result_error_nomem(ctx);
3418 }
drheb18ae32023-12-03 00:51:303419 return 0;
drhbfc7e622023-11-30 00:52:333420}
3421
drh8a4ceca2023-11-21 17:51:583422/* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent
drh4d9384c2025-03-31 23:18:063423** arguments come in pairs where each pair contains a JSON path and
drh8a4ceca2023-11-21 17:51:583424** content to insert or set at that patch. Do the updates
3425** and return the result.
3426**
3427** The specific operation is determined by eEdit, which can be one
3428** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET.
3429*/
3430static void jsonInsertIntoBlob(
3431 sqlite3_context *ctx,
3432 int argc,
3433 sqlite3_value **argv,
3434 int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */
3435){
3436 int i;
drhcf726062023-11-21 22:36:323437 u32 rc = 0;
drh8a4ceca2023-11-21 17:51:583438 const char *zPath = 0;
3439 int flgs;
drhbfc7e622023-11-30 00:52:333440 JsonParse *p;
3441 JsonParse ax;
drh8a4ceca2023-11-21 17:51:583442
3443 assert( (argc&1)==1 );
drhbfc7e622023-11-30 00:52:333444 flgs = argc==1 ? 0 : JSON_EDITABLE;
3445 p = jsonParseFuncArg(ctx, argv[0], flgs);
3446 if( p==0 ) return;
drh8a4ceca2023-11-21 17:51:583447 for(i=1; i<argc-1; i+=2){
drhbfc7e622023-11-30 00:52:333448 if( sqlite3_value_type(argv[i])==SQLITE_NULL ) continue;
3449 zPath = (const char*)sqlite3_value_text(argv[i]);
3450 if( zPath==0 ){
3451 sqlite3_result_error_nomem(ctx);
3452 jsonParseFree(p);
3453 return;
3454 }
drh8a4ceca2023-11-21 17:51:583455 if( zPath[0]!='$' ) goto jsonInsertIntoBlob_patherror;
3456 if( jsonFunctionArgToBlob(ctx, argv[i+1], &ax) ){
drhbfc7e622023-11-30 00:52:333457 jsonParseReset(&ax);
3458 jsonParseFree(p);
3459 return;
drh8a4ceca2023-11-21 17:51:583460 }
3461 if( zPath[1]==0 ){
drhbfc7e622023-11-30 00:52:333462 if( eEdit==JEDIT_REPL || eEdit==JEDIT_SET ){
3463 jsonBlobEdit(p, 0, p->nBlob, ax.aBlob, ax.nBlob);
3464 }
3465 rc = 0;
3466 }else{
3467 p->eEdit = eEdit;
3468 p->nIns = ax.nBlob;
3469 p->aIns = ax.aBlob;
3470 p->delta = 0;
drh53c21602023-12-02 18:17:383471 rc = jsonLookupStep(p, 0, zPath+1, 0);
drh8a4ceca2023-11-21 17:51:583472 }
drhab702662023-11-24 14:25:563473 jsonParseReset(&ax);
drh53c21602023-12-02 18:17:383474 if( rc==JSON_LOOKUP_NOTFOUND ) continue;
3475 if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror;
drh8a4ceca2023-11-21 17:51:583476 }
drhbfc7e622023-11-30 00:52:333477 jsonReturnParse(ctx, p);
3478 jsonParseFree(p);
drh8a4ceca2023-11-21 17:51:583479 return;
3480
3481jsonInsertIntoBlob_patherror:
drhbfc7e622023-11-30 00:52:333482 jsonParseFree(p);
drh53c21602023-12-02 18:17:383483 if( rc==JSON_LOOKUP_ERROR ){
drhcf726062023-11-21 22:36:323484 sqlite3_result_error(ctx, "malformed JSON", -1);
3485 }else{
drhbfc7e622023-11-30 00:52:333486 jsonBadPathError(ctx, zPath);
drhcf726062023-11-21 22:36:323487 }
drh8a4ceca2023-11-21 17:51:583488 return;
3489}
3490
drhef97f832023-11-28 18:16:023491/*
drh41fb2ee2024-01-22 14:16:103492** If pArg is a blob that seems like a JSONB blob, then initialize
3493** p to point to that JSONB and return TRUE. If pArg does not seem like
drhcbe4a262025-04-21 19:53:123494** a JSONB blob, then return FALSE.
drh41fb2ee2024-01-22 14:16:103495**
drhcbe4a262025-04-21 19:53:123496** For small BLOBs (having no more than 7 bytes of payload) a full
3497** validity check is done. So for small BLOBs this routine only returns
3498** true if the value is guaranteed to be a valid JSONB. For larger BLOBs
3499** (8 byte or more of payload) only the size of the outermost element is
3500** checked to verify that the BLOB is superficially valid JSONB.
3501**
3502** A full JSONB validation is done on smaller BLOBs because those BLOBs might
3503** also be text JSON that has been incorrectly cast into a BLOB.
3504** (See tag-20240123-a and https://sqlite.org/forum/forumpost/012136abd5)
3505** If the BLOB is 9 bytes are larger, then it is not possible for the
3506** superficial size check done here to pass if the input is really text
3507** JSON so we do not need to look deeper in that case.
3508**
3509** Why we only need to do full JSONB validation for smaller BLOBs:
3510**
3511** The first byte of valid JSON text must be one of: '{', '[', '"', ' ', '\n',
3512** '\r', '\t', '-', or a digit '0' through '9'. Of these, only a subset
drh81cde802025-04-21 20:58:493513** can also be the first byte of JSONB: '{', '[', and digits '3'
drhcbe4a262025-04-21 19:53:123514** through '9'. In every one of those cases, the payload size is 7 bytes
3515** or less. So if we do full JSONB validation for every BLOB where the
3516** payload is less than 7 bytes, we will never get a false positive for
3517** JSONB on an input that is really text JSON.
drh41fb2ee2024-01-22 14:16:103518*/
3519static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){
3520 u32 n, sz = 0;
drh81cde802025-04-21 20:58:493521 u8 c;
drhcbe4a262025-04-21 19:53:123522 if( sqlite3_value_type(pArg)!=SQLITE_BLOB ) return 0;
drh41fb2ee2024-01-22 14:16:103523 p->aBlob = (u8*)sqlite3_value_blob(pArg);
3524 p->nBlob = (u32)sqlite3_value_bytes(pArg);
drhcbe4a262025-04-21 19:53:123525 if( p->nBlob>0
3526 && ALWAYS(p->aBlob!=0)
drh81cde802025-04-21 20:58:493527 && ((c = p->aBlob[0]) & 0x0f)<=JSONB_OBJECT
drh41fb2ee2024-01-22 14:16:103528 && (n = jsonbPayloadSize(p, 0, &sz))>0
3529 && sz+n==p->nBlob
drh81cde802025-04-21 20:58:493530 && ((c & 0x0f)>JSONB_FALSE || sz==0)
3531 && (sz>7
3532 || (c!=0x7b && c!=0x5b && !sqlite3Isdigit(c))
3533 || jsonbValidityCheck(p, 0, p->nBlob, 1)==0)
drh41fb2ee2024-01-22 14:16:103534 ){
3535 return 1;
3536 }
3537 p->aBlob = 0;
3538 p->nBlob = 0;
3539 return 0;
3540}
3541
3542/*
drhef97f832023-11-28 18:16:023543** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob,
3544** from the SQL function argument pArg. Return a pointer to the new
3545** JsonParse object.
3546**
3547** Ownership of the new JsonParse object is passed to the caller. The
3548** caller should invoke jsonParseFree() on the return value when it
3549** has finished using it.
3550**
3551** If any errors are detected, an appropriate error messages is set
3552** using sqlite3_result_error() or the equivalent and this routine
3553** returns NULL. This routine also returns NULL if the pArg argument
3554** is an SQL NULL value, but no error message is set in that case. This
3555** is so that SQL functions that are given NULL arguments will return
3556** a NULL value.
3557*/
3558static JsonParse *jsonParseFuncArg(
3559 sqlite3_context *ctx,
3560 sqlite3_value *pArg,
3561 u32 flgs
3562){
drh063d0d42023-12-01 18:46:143563 int eType; /* Datatype of pArg */
3564 JsonParse *p = 0; /* Value to be returned */
3565 JsonParse *pFromCache = 0; /* Value taken from cache */
drh4093b292024-01-03 16:41:503566 sqlite3 *db; /* The database connection */
drhef97f832023-11-28 18:16:023567
3568 assert( ctx!=0 );
3569 eType = sqlite3_value_type(pArg);
3570 if( eType==SQLITE_NULL ){
3571 return 0;
3572 }
drh063d0d42023-12-01 18:46:143573 pFromCache = jsonCacheSearch(ctx, pArg);
3574 if( pFromCache ){
3575 pFromCache->nJPRef++;
3576 if( (flgs & JSON_EDITABLE)==0 ){
3577 return pFromCache;
3578 }
3579 }
drh4093b292024-01-03 16:41:503580 db = sqlite3_context_db_handle(ctx);
drh063d0d42023-12-01 18:46:143581rebuild_from_cache:
drh4093b292024-01-03 16:41:503582 p = sqlite3DbMallocZero(db, sizeof(*p));
drhef97f832023-11-28 18:16:023583 if( p==0 ) goto json_pfa_oom;
3584 memset(p, 0, sizeof(*p));
drh4093b292024-01-03 16:41:503585 p->db = db;
drh063d0d42023-12-01 18:46:143586 p->nJPRef = 1;
3587 if( pFromCache!=0 ){
3588 u32 nBlob = pFromCache->nBlob;
drh4093b292024-01-03 16:41:503589 p->aBlob = sqlite3DbMallocRaw(db, nBlob);
drh063d0d42023-12-01 18:46:143590 if( p->aBlob==0 ) goto json_pfa_oom;
3591 memcpy(p->aBlob, pFromCache->aBlob, nBlob);
3592 p->nBlobAlloc = p->nBlob = nBlob;
3593 p->hasNonstd = pFromCache->hasNonstd;
3594 jsonParseFree(pFromCache);
3595 return p;
drh063d0d42023-12-01 18:46:143596 }
drhef97f832023-11-28 18:16:023597 if( eType==SQLITE_BLOB ){
drh41fb2ee2024-01-22 14:16:103598 if( jsonArgIsJsonb(pArg,p) ){
3599 if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){
3600 goto json_pfa_oom;
3601 }
3602 return p;
drhef97f832023-11-28 18:16:023603 }
drhe318f102024-01-23 13:21:403604 /* If the blob is not valid JSONB, fall through into trying to cast
3605 ** the blob into text which is then interpreted as JSON. (tag-20240123-a)
3606 **
3607 ** This goes against all historical documentation about how the SQLite
3608 ** JSON functions were suppose to work. From the beginning, blob was
3609 ** reserved for expansion and a blob value should have raised an error.
3610 ** But it did not, due to a bug. And many applications came to depend
stephanda5f8132025-02-27 21:17:553611 ** upon this buggy behavior, especially when using the CLI and reading
drhe318f102024-01-23 13:21:403612 ** JSON text using readfile(), which returns a blob. For this reason
3613 ** we will continue to support the bug moving forward.
3614 ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d
3615 */
drhef97f832023-11-28 18:16:023616 }
drhef97f832023-11-28 18:16:023617 p->zJson = (char*)sqlite3_value_text(pArg);
3618 p->nJson = sqlite3_value_bytes(pArg);
drh8babc012024-02-06 18:33:013619 if( db->mallocFailed ) goto json_pfa_oom;
drhef97f832023-11-28 18:16:023620 if( p->nJson==0 ) goto json_pfa_malformed;
drh8babc012024-02-06 18:33:013621 assert( p->zJson!=0 );
drh063d0d42023-12-01 18:46:143622 if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){
drh38aeb972023-11-30 20:57:483623 if( flgs & JSON_KEEPERROR ){
3624 p->nErr = 1;
3625 return p;
3626 }else{
3627 jsonParseFree(p);
3628 return 0;
3629 }
drh063d0d42023-12-01 18:46:143630 }else{
drh5bfa7e62023-12-01 13:28:133631 int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref);
drh063d0d42023-12-01 18:46:143632 int rc;
3633 if( !isRCStr ){
3634 char *zNew = sqlite3RCStrNew( p->nJson );
3635 if( zNew==0 ) goto json_pfa_oom;
3636 memcpy(zNew, p->zJson, p->nJson);
3637 p->zJson = zNew;
3638 p->zJson[p->nJson] = 0;
3639 }else{
3640 sqlite3RCStrRef(p->zJson);
3641 }
3642 p->bJsonIsRCStr = 1;
3643 rc = jsonCacheInsert(ctx, p);
drh5bfa7e62023-12-01 13:28:133644 if( rc==SQLITE_NOMEM ) goto json_pfa_oom;
drh063d0d42023-12-01 18:46:143645 if( flgs & JSON_EDITABLE ){
3646 pFromCache = p;
3647 p = 0;
3648 goto rebuild_from_cache;
3649 }
drh5bfa7e62023-12-01 13:28:133650 }
drhef97f832023-11-28 18:16:023651 return p;
3652
3653json_pfa_malformed:
drh38aeb972023-11-30 20:57:483654 if( flgs & JSON_KEEPERROR ){
3655 p->nErr = 1;
3656 return p;
3657 }else{
3658 jsonParseFree(p);
3659 sqlite3_result_error(ctx, "malformed JSON", -1);
3660 return 0;
3661 }
drhef97f832023-11-28 18:16:023662
3663json_pfa_oom:
drh063d0d42023-12-01 18:46:143664 jsonParseFree(pFromCache);
drhef97f832023-11-28 18:16:023665 jsonParseFree(p);
3666 sqlite3_result_error_nomem(ctx);
3667 return 0;
3668}
3669
3670/*
3671** Make the return value of a JSON function either the raw JSONB blob
3672** or make it JSON text, depending on whether the JSON_BLOB flag is
3673** set on the function.
3674*/
3675static void jsonReturnParse(
3676 sqlite3_context *ctx,
3677 JsonParse *p
3678){
3679 int flgs;
drh66795962023-11-30 19:06:273680 if( p->oom ){
3681 sqlite3_result_error_nomem(ctx);
3682 return;
3683 }
drhef97f832023-11-28 18:16:023684 flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
3685 if( flgs & JSON_BLOB ){
drha11aaff2023-12-02 18:04:273686 if( p->nBlobAlloc>0 && !p->bReadOnly ){
3687 sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC);
3688 p->nBlobAlloc = 0;
3689 }else{
3690 sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT);
3691 }
drhef97f832023-11-28 18:16:023692 }else{
3693 JsonString s;
3694 jsonStringInit(&s, ctx);
drh095f2c52023-12-18 15:53:483695 p->delta = 0;
drh3262ca82023-12-19 21:39:583696 jsonTranslateBlobToText(p, 0, &s);
drhca1ce772023-12-01 12:57:123697 jsonReturnString(&s, p, ctx);
drhef97f832023-11-28 18:16:023698 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
3699 }
3700}
3701
drh987eb1f2015-08-17 15:17:373702/****************************************************************************
3703** SQL functions used for testing and debugging
3704****************************************************************************/
drhe9c37f32015-08-15 21:25:363705
drh7286c592023-07-26 13:17:433706#if SQLITE_DEBUG
drh9125d5a2023-07-24 17:59:253707/*
drh8a3034a2023-11-27 17:13:183708** Decode JSONB bytes in aBlob[] starting at iStart through but not
3709** including iEnd. Indent the
3710** content by nIndent spaces.
3711*/
3712static void jsonDebugPrintBlob(
3713 JsonParse *pParse, /* JSON content */
3714 u32 iStart, /* Start rendering here */
3715 u32 iEnd, /* Do not render this byte or any byte after this one */
drh0546a282023-12-28 16:21:223716 int nIndent, /* Indent by this many spaces */
3717 sqlite3_str *pOut /* Generate output into this sqlite3_str object */
drh8a3034a2023-11-27 17:13:183718){
3719 while( iStart<iEnd ){
3720 u32 i, n, nn, sz = 0;
3721 int showContent = 1;
3722 u8 x = pParse->aBlob[iStart] & 0x0f;
drhda257832023-11-29 17:36:543723 u32 savedNBlob = pParse->nBlob;
drh0546a282023-12-28 16:21:223724 sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, "");
drhda257832023-11-29 17:36:543725 if( pParse->nBlobAlloc>pParse->nBlob ){
3726 pParse->nBlob = pParse->nBlobAlloc;
3727 }
drh8a3034a2023-11-27 17:13:183728 nn = n = jsonbPayloadSize(pParse, iStart, &sz);
3729 if( nn==0 ) nn = 1;
3730 if( sz>0 && x<JSONB_ARRAY ){
3731 nn += sz;
3732 }
drh0546a282023-12-28 16:21:223733 for(i=0; i<nn; i++){
3734 sqlite3_str_appendf(pOut, " %02x", pParse->aBlob[iStart+i]);
3735 }
drhda257832023-11-29 17:36:543736 if( n==0 ){
drh0546a282023-12-28 16:21:223737 sqlite3_str_appendf(pOut, " ERROR invalid node size\n");
drh8a3034a2023-11-27 17:13:183738 iStart = n==0 ? iStart+1 : iEnd;
3739 continue;
3740 }
drhda257832023-11-29 17:36:543741 pParse->nBlob = savedNBlob;
3742 if( iStart+n+sz>iEnd ){
3743 iEnd = iStart+n+sz;
3744 if( iEnd>pParse->nBlob ){
3745 if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){
3746 iEnd = pParse->nBlobAlloc;
3747 }else{
3748 iEnd = pParse->nBlob;
3749 }
3750 }
3751 }
drh0546a282023-12-28 16:21:223752 sqlite3_str_appendall(pOut," <-- ");
drh8a3034a2023-11-27 17:13:183753 switch( x ){
drh0546a282023-12-28 16:21:223754 case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break;
3755 case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break;
3756 case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break;
3757 case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break;
3758 case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break;
3759 case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break;
3760 case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break;
3761 case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break;
3762 case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break;
3763 case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break;
3764 case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break;
drh8a3034a2023-11-27 17:13:183765 case JSONB_ARRAY: {
drh0546a282023-12-28 16:21:223766 sqlite3_str_appendf(pOut,"array, %u bytes\n", sz);
3767 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
drh8a3034a2023-11-27 17:13:183768 showContent = 0;
3769 break;
3770 }
3771 case JSONB_OBJECT: {
drh0546a282023-12-28 16:21:223772 sqlite3_str_appendf(pOut, "object, %u bytes\n", sz);
3773 jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut);
drh8a3034a2023-11-27 17:13:183774 showContent = 0;
3775 break;
3776 }
3777 default: {
drh0546a282023-12-28 16:21:223778 sqlite3_str_appendall(pOut, "ERROR: unknown node type\n");
drh8a3034a2023-11-27 17:13:183779 showContent = 0;
3780 break;
3781 }
3782 }
3783 if( showContent ){
drh4b9ed1b2023-11-30 23:36:143784 if( sz==0 && x<=JSONB_FALSE ){
drh0546a282023-12-28 16:21:223785 sqlite3_str_append(pOut, "\n", 1);
drh8a3034a2023-11-27 17:13:183786 }else{
mistachkin3ab9c022024-02-04 04:01:113787 u32 j;
drh0546a282023-12-28 16:21:223788 sqlite3_str_appendall(pOut, ": \"");
mistachkin3ab9c022024-02-04 04:01:113789 for(j=iStart+n; j<iStart+n+sz; j++){
3790 u8 c = pParse->aBlob[j];
drh8a3034a2023-11-27 17:13:183791 if( c<0x20 || c>=0x7f ) c = '.';
drh0546a282023-12-28 16:21:223792 sqlite3_str_append(pOut, (char*)&c, 1);
drh8a3034a2023-11-27 17:13:183793 }
drh0546a282023-12-28 16:21:223794 sqlite3_str_append(pOut, "\"\n", 2);
drh8a3034a2023-11-27 17:13:183795 }
3796 }
3797 iStart += n + sz;
3798 }
3799}
drhef97f832023-11-28 18:16:023800static void jsonShowParse(JsonParse *pParse){
drh0546a282023-12-28 16:21:223801 sqlite3_str out;
3802 char zBuf[1000];
drhef97f832023-11-28 18:16:023803 if( pParse==0 ){
3804 printf("NULL pointer\n");
3805 return;
3806 }else{
drhda257832023-11-29 17:36:543807 printf("nBlobAlloc = %u\n", pParse->nBlobAlloc);
3808 printf("nBlob = %u\n", pParse->nBlob);
3809 printf("delta = %d\n", pParse->delta);
3810 if( pParse->nBlob==0 ) return;
3811 printf("content (bytes 0..%u):\n", pParse->nBlob-1);
drhef97f832023-11-28 18:16:023812 }
drh0546a282023-12-28 16:21:223813 sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000);
3814 jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out);
3815 printf("%s", sqlite3_str_value(&out));
3816 sqlite3_str_reset(&out);
drhef97f832023-11-28 18:16:023817}
drh8a3034a2023-11-27 17:13:183818#endif /* SQLITE_DEBUG */
3819
drh301eecc2015-08-17 20:14:193820#ifdef SQLITE_DEBUG
drhe9c37f32015-08-15 21:25:363821/*
drh7286c592023-07-26 13:17:433822** SQL function: json_parse(JSON)
3823**
drh0546a282023-12-28 16:21:223824** Parse JSON using jsonParseFuncArg(). Return text that is a
3825** human-readable dump of the binary JSONB for the input parameter.
drhe9c37f32015-08-15 21:25:363826*/
drh5634cc02015-08-17 11:28:033827static void jsonParseFunc(
drhbc8f0922015-08-22 19:39:043828 sqlite3_context *ctx,
drhe9c37f32015-08-15 21:25:363829 int argc,
3830 sqlite3_value **argv
3831){
drh7286c592023-07-26 13:17:433832 JsonParse *p; /* The parse */
drh0546a282023-12-28 16:21:223833 sqlite3_str out;
drhe9c37f32015-08-15 21:25:363834
drh0546a282023-12-28 16:21:223835 assert( argc>=1 );
3836 sqlite3StrAccumInit(&out, 0, 0, 0, 1000000);
drhef97f832023-11-28 18:16:023837 p = jsonParseFuncArg(ctx, argv[0], 0);
drh0546a282023-12-28 16:21:223838 if( p==0 ) return;
3839 if( argc==1 ){
3840 jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out);
drhb202a452024-01-31 12:15:573841 sqlite3_result_text64(ctx,out.zText,out.nChar,SQLITE_TRANSIENT,SQLITE_UTF8);
drh0546a282023-12-28 16:21:223842 }else{
3843 jsonShowParse(p);
3844 }
drhef97f832023-11-28 18:16:023845 jsonParseFree(p);
drhb202a452024-01-31 12:15:573846 sqlite3_str_reset(&out);
drhe9c37f32015-08-15 21:25:363847}
drh301eecc2015-08-17 20:14:193848#endif /* SQLITE_DEBUG */
drh5634cc02015-08-17 11:28:033849
drh987eb1f2015-08-17 15:17:373850/****************************************************************************
drhff135ae2015-12-30 01:07:023851** Scalar SQL function implementations
drh987eb1f2015-08-17 15:17:373852****************************************************************************/
3853
3854/*
drh59335812023-09-25 13:23:293855** Implementation of the json_quote(VALUE) function. Return a JSON value
drh77253702023-07-26 11:43:393856** corresponding to the SQL value input. Mostly this means putting
drh2ad96f52016-06-17 13:01:513857** double-quotes around strings and returning the unquoted string "null"
3858** when given a NULL input.
3859*/
3860static void jsonQuoteFunc(
3861 sqlite3_context *ctx,
3862 int argc,
3863 sqlite3_value **argv
3864){
3865 JsonString jx;
drh9dbf96b2022-01-06 01:40:093866 UNUSED_PARAMETER(argc);
drh2ad96f52016-06-17 13:01:513867
drhae5f55e2023-09-29 12:45:143868 jsonStringInit(&jx, ctx);
3869 jsonAppendSqlValue(&jx, argv[0]);
drhca1ce772023-12-01 12:57:123870 jsonReturnString(&jx, 0, 0);
drh2ad96f52016-06-17 13:01:513871 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
3872}
3873
3874/*
drh987eb1f2015-08-17 15:17:373875** Implementation of the json_array(VALUE,...) function. Return a JSON
3876** array that contains all values given in arguments. Or if any argument
3877** is a BLOB, throw an error.
3878*/
3879static void jsonArrayFunc(
drhbc8f0922015-08-22 19:39:043880 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:373881 int argc,
3882 sqlite3_value **argv
3883){
3884 int i;
drh505ad2c2015-08-21 17:33:113885 JsonString jx;
drh987eb1f2015-08-17 15:17:373886
drhae5f55e2023-09-29 12:45:143887 jsonStringInit(&jx, ctx);
drhd0960592015-08-17 21:22:323888 jsonAppendChar(&jx, '[');
drh987eb1f2015-08-17 15:17:373889 for(i=0; i<argc; i++){
drhd0960592015-08-17 21:22:323890 jsonAppendSeparator(&jx);
drhae5f55e2023-09-29 12:45:143891 jsonAppendSqlValue(&jx, argv[i]);
drh987eb1f2015-08-17 15:17:373892 }
drhd0960592015-08-17 21:22:323893 jsonAppendChar(&jx, ']');
drhca1ce772023-12-01 12:57:123894 jsonReturnString(&jx, 0, 0);
drhf5ddb9c2015-09-11 00:06:413895 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:373896}
3897
drh4b54d6c2023-11-29 01:38:153898/*
drh987eb1f2015-08-17 15:17:373899** json_array_length(JSON)
3900** json_array_length(JSON, PATH)
3901**
drh77253702023-07-26 11:43:393902** Return the number of elements in the top-level JSON array.
drh987eb1f2015-08-17 15:17:373903** Return 0 if the input is not a well-formed JSON array.
3904*/
3905static void jsonArrayLengthFunc(
drhbc8f0922015-08-22 19:39:043906 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:373907 int argc,
3908 sqlite3_value **argv
3909){
drh3fb153c2017-05-11 16:49:593910 JsonParse *p; /* The parse */
drh4b54d6c2023-11-29 01:38:153911 sqlite3_int64 cnt = 0;
drh987eb1f2015-08-17 15:17:373912 u32 i;
drh4b54d6c2023-11-29 01:38:153913 u8 eErr = 0;
drh987eb1f2015-08-17 15:17:373914
drh4b54d6c2023-11-29 01:38:153915 p = jsonParseFuncArg(ctx, argv[0], 0);
drh3fb153c2017-05-11 16:49:593916 if( p==0 ) return;
drha8f39a92015-09-21 22:53:163917 if( argc==2 ){
3918 const char *zPath = (const char*)sqlite3_value_text(argv[1]);
drh4b54d6c2023-11-29 01:38:153919 if( zPath==0 ){
3920 jsonParseFree(p);
3921 return;
3922 }
drh53c21602023-12-02 18:17:383923 i = jsonLookupStep(p, 0, zPath[0]=='$' ? zPath+1 : "@", 0);
3924 if( JSON_LOOKUP_ISERROR(i) ){
3925 if( i==JSON_LOOKUP_NOTFOUND ){
drh4b54d6c2023-11-29 01:38:153926 /* no-op */
drh53c21602023-12-02 18:17:383927 }else if( i==JSON_LOOKUP_PATHERROR ){
drh4b54d6c2023-11-29 01:38:153928 jsonBadPathError(ctx, zPath);
3929 }else{
3930 sqlite3_result_error(ctx, "malformed JSON", -1);
drh0f200bc2023-07-26 00:48:453931 }
drh4b54d6c2023-11-29 01:38:153932 eErr = 1;
3933 i = 0;
3934 }
3935 }else{
3936 i = 0;
3937 }
3938 if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){
drhc1e85742023-12-02 20:25:363939 cnt = jsonbArrayCount(p, i);
drh987eb1f2015-08-17 15:17:373940 }
drhf26e26a2023-12-04 19:32:173941 if( !eErr ) sqlite3_result_int64(ctx, cnt);
drh4b54d6c2023-11-29 01:38:153942 jsonParseFree(p);
drh1cab41e2023-11-28 20:25:233943}
3944
drh6a8581d2023-12-06 15:35:383945/* True if the string is all alphanumerics and underscores */
3946static int jsonAllAlphanum(const char *z, int n){
3947 int i;
3948 for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){}
3949 return i==n;
3950}
3951
drh1cab41e2023-11-28 20:25:233952/*
drh3ad93bb2015-08-29 19:41:453953** json_extract(JSON, PATH, ...)
drhdc60c682022-01-08 15:05:533954** "->"(JSON,PATH)
3955** "->>"(JSON,PATH)
drh987eb1f2015-08-17 15:17:373956**
drhdc60c682022-01-08 15:05:533957** Return the element described by PATH. Return NULL if that PATH element
drhd83c90b2022-01-10 15:43:133958** is not found.
drhdc60c682022-01-08 15:05:533959**
drhd83c90b2022-01-10 15:43:133960** If JSON_JSON is set or if more that one PATH argument is supplied then
3961** always return a JSON representation of the result. If JSON_SQL is set,
3962** then always return an SQL representation of the result. If neither flag
3963** is present and argc==2, then return JSON for objects and arrays and SQL
3964** for all other values.
drhdc60c682022-01-08 15:05:533965**
drhd83c90b2022-01-10 15:43:133966** When multiple PATH arguments are supplied, the result is a JSON array
3967** containing the result of each PATH.
drhdc60c682022-01-08 15:05:533968**
drhd83c90b2022-01-10 15:43:133969** Abbreviated JSON path expressions are allows if JSON_ABPATH, for
3970** compatibility with PG.
drh987eb1f2015-08-17 15:17:373971*/
3972static void jsonExtractFunc(
drhbc8f0922015-08-22 19:39:043973 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:373974 int argc,
3975 sqlite3_value **argv
3976){
drh1cab41e2023-11-28 20:25:233977 JsonParse *p = 0; /* The parse */
3978 int flags; /* Flags associated with the function */
3979 int i; /* Loop counter */
3980 JsonString jx; /* String for array result */
drh3ad93bb2015-08-29 19:41:453981
3982 if( argc<2 ) return;
drh1cab41e2023-11-28 20:25:233983 p = jsonParseFuncArg(ctx, argv[0], 0);
drhd83c90b2022-01-10 15:43:133984 if( p==0 ) return;
drh1cab41e2023-11-28 20:25:233985 flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
3986 jsonStringInit(&jx, ctx);
3987 if( argc>2 ){
drh12b9fa92022-01-07 15:47:123988 jsonAppendChar(&jx, '[');
drh1cab41e2023-11-28 20:25:233989 }
3990 for(i=1; i<argc; i++){
3991 /* With a single PATH argument */
3992 const char *zPath = (const char*)sqlite3_value_text(argv[i]);
drh16e8a5b2023-12-03 23:30:593993 int nPath;
drh1cab41e2023-11-28 20:25:233994 u32 j;
3995 if( zPath==0 ) goto json_extract_error;
drh16e8a5b2023-12-03 23:30:593996 nPath = sqlite3Strlen30(zPath);
drh1cab41e2023-11-28 20:25:233997 if( zPath[0]=='$' ){
drh53c21602023-12-02 18:17:383998 j = jsonLookupStep(p, 0, zPath+1, 0);
drh1cab41e2023-11-28 20:25:233999 }else if( (flags & JSON_ABPATH) ){
4000 /* The -> and ->> operators accept abbreviated PATH arguments. This
4001 ** is mostly for compatibility with PostgreSQL, but also for
4002 ** convenience.
4003 **
4004 ** NUMBER ==> $[NUMBER] // PG compatible
4005 ** LABEL ==> $.LABEL // PG compatible
4006 ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
drhfefe24d2024-05-27 13:24:394007 **
4008 ** Updated 2024-05-27: If the NUMBER is negative, then PG counts from
stephan20c118f2024-05-27 13:41:464009 ** the right of the array. Hence for negative NUMBER:
drhfefe24d2024-05-27 13:24:394010 **
4011 ** NUMBER ==> $[#NUMBER] // PG compatible
drh1cab41e2023-11-28 20:25:234012 */
4013 jsonStringInit(&jx, ctx);
drhb8337932024-05-21 11:11:294014 if( sqlite3_value_type(argv[i])==SQLITE_INTEGER ){
drh1cab41e2023-11-28 20:25:234015 jsonAppendRawNZ(&jx, "[", 1);
drhfefe24d2024-05-27 13:24:394016 if( zPath[0]=='-' ) jsonAppendRawNZ(&jx,"#",1);
drh1ef232c2023-11-28 20:33:204017 jsonAppendRaw(&jx, zPath, nPath);
drh1cab41e2023-11-28 20:25:234018 jsonAppendRawNZ(&jx, "]", 2);
drh6a8581d2023-12-06 15:35:384019 }else if( jsonAllAlphanum(zPath, nPath) ){
drh1cab41e2023-11-28 20:25:234020 jsonAppendRawNZ(&jx, ".", 1);
drh1ef232c2023-11-28 20:33:204021 jsonAppendRaw(&jx, zPath, nPath);
drh6a8581d2023-12-06 15:35:384022 }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){
drh1ef232c2023-11-28 20:33:204023 jsonAppendRaw(&jx, zPath, nPath);
drh6a8581d2023-12-06 15:35:384024 }else{
4025 jsonAppendRawNZ(&jx, ".\"", 2);
4026 jsonAppendRaw(&jx, zPath, nPath);
4027 jsonAppendRawNZ(&jx, "\"", 1);
drh1cab41e2023-11-28 20:25:234028 }
4029 jsonStringTerminate(&jx);
drh53c21602023-12-02 18:17:384030 j = jsonLookupStep(p, 0, jx.zBuf, 0);
drh1cab41e2023-11-28 20:25:234031 jsonStringReset(&jx);
4032 }else{
drh4b54d6c2023-11-29 01:38:154033 jsonBadPathError(ctx, zPath);
drh1cab41e2023-11-28 20:25:234034 goto json_extract_error;
4035 }
4036 if( j<p->nBlob ){
4037 if( argc==2 ){
4038 if( flags & JSON_JSON ){
4039 jsonStringInit(&jx, ctx);
drh3262ca82023-12-19 21:39:584040 jsonTranslateBlobToText(p, j, &jx);
drhca1ce772023-12-01 12:57:124041 jsonReturnString(&jx, 0, 0);
drh1cab41e2023-11-28 20:25:234042 jsonStringReset(&jx);
drh1f8c7c72023-11-28 23:18:044043 assert( (flags & JSON_BLOB)==0 );
drh1cab41e2023-11-28 20:25:234044 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
4045 }else{
4046 jsonReturnFromBlob(p, j, ctx, 0);
drh1f8c7c72023-11-28 23:18:044047 if( (flags & (JSON_SQL|JSON_BLOB))==0
4048 && (p->aBlob[j]&0x0f)>=JSONB_ARRAY
4049 ){
drh1cab41e2023-11-28 20:25:234050 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
4051 }
4052 }
drh3ad93bb2015-08-29 19:41:454053 }else{
drh1cab41e2023-11-28 20:25:234054 jsonAppendSeparator(&jx);
drh3262ca82023-12-19 21:39:584055 jsonTranslateBlobToText(p, j, &jx);
drh1cab41e2023-11-28 20:25:234056 }
drh53c21602023-12-02 18:17:384057 }else if( j==JSON_LOOKUP_NOTFOUND ){
drh1cab41e2023-11-28 20:25:234058 if( argc==2 ){
4059 goto json_extract_error; /* Return NULL if not found */
4060 }else{
4061 jsonAppendSeparator(&jx);
drh8376ae72023-07-19 15:06:294062 jsonAppendRawNZ(&jx, "null", 4);
drh3ad93bb2015-08-29 19:41:454063 }
drh53c21602023-12-02 18:17:384064 }else if( j==JSON_LOOKUP_ERROR ){
drh1cab41e2023-11-28 20:25:234065 sqlite3_result_error(ctx, "malformed JSON", -1);
4066 goto json_extract_error;
4067 }else{
drh4b54d6c2023-11-29 01:38:154068 jsonBadPathError(ctx, zPath);
drh1cab41e2023-11-28 20:25:234069 goto json_extract_error;
drh3ad93bb2015-08-29 19:41:454070 }
drh987eb1f2015-08-17 15:17:374071 }
drh1cab41e2023-11-28 20:25:234072 if( argc>2 ){
4073 jsonAppendChar(&jx, ']');
drhca1ce772023-12-01 12:57:124074 jsonReturnString(&jx, 0, 0);
drh1f8c7c72023-11-28 23:18:044075 if( (flags & JSON_BLOB)==0 ){
4076 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
4077 }
drh1cab41e2023-11-28 20:25:234078 }
4079json_extract_error:
4080 jsonStringReset(&jx);
4081 jsonParseFree(p);
4082 return;
drh987eb1f2015-08-17 15:17:374083}
4084
drheb04a0b2023-11-27 23:46:124085/*
drh3cdb0792023-12-04 23:12:574086** Return codes for jsonMergePatch()
drheb04a0b2023-11-27 23:46:124087*/
4088#define JSON_MERGE_OK 0 /* Success */
4089#define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */
4090#define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */
4091#define JSON_MERGE_OOM 3 /* Out-of-memory condition */
4092
4093/*
4094** RFC-7396 MergePatch for two JSONB blobs.
4095**
4096** pTarget is the target. pPatch is the patch. The target is updated
4097** in place. The patch is read-only.
4098**
4099** The original RFC-7396 algorithm is this:
4100**
4101** define MergePatch(Target, Patch):
4102** if Patch is an Object:
4103** if Target is not an Object:
4104** Target = {} # Ignore the contents and set it to an empty Object
4105** for each Name/Value pair in Patch:
4106** if Value is null:
4107** if Name exists in Target:
4108** remove the Name/Value pair from Target
4109** else:
4110** Target[Name] = MergePatch(Target[Name], Value)
4111** return Target
4112** else:
4113** return Patch
4114**
drhf46f89d2023-11-28 00:27:584115** Here is an equivalent algorithm restructured to show the actual
drheb04a0b2023-11-27 23:46:124116** implementation:
4117**
4118** 01 define MergePatch(Target, Patch):
4119** 02 if Patch is not an Object:
4120** 03 return Patch
drhf46f89d2023-11-28 00:27:584121** 04 else: // if Patch is an Object
drheb04a0b2023-11-27 23:46:124122** 05 if Target is not an Object:
4123** 06 Target = {}
4124** 07 for each Name/Value pair in Patch:
4125** 08 if Name exists in Target:
4126** 09 if Value is null:
4127** 10 remove the Name/Value pair from Target
4128** 11 else
4129** 12 Target[name] = MergePatch(Target[Name], Value)
4130** 13 else if Value is not NULL:
drhf46f89d2023-11-28 00:27:584131** 14 if Value is not an Object:
4132** 15 Target[name] = Value
4133** 16 else:
4134** 17 Target[name] = MergePatch('{}',value)
4135** 18 return Target
drheb04a0b2023-11-27 23:46:124136** |
4137** ^---- Line numbers referenced in comments in the implementation
4138*/
drh3cdb0792023-12-04 23:12:574139static int jsonMergePatch(
drheb04a0b2023-11-27 23:46:124140 JsonParse *pTarget, /* The JSON parser that contains the TARGET */
4141 u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */
drh5026ddb2023-11-28 12:28:284142 const JsonParse *pPatch, /* The PATCH */
drheb04a0b2023-11-27 23:46:124143 u32 iPatch /* Index of PATCH in pPatch->aBlob[] */
4144){
4145 u8 x; /* Type of a single node */
4146 u32 n, sz=0; /* Return values from jsonbPayloadSize() */
4147 u32 iTCursor; /* Cursor position while scanning the target object */
4148 u32 iTStart; /* First label in the target object */
4149 u32 iTEndBE; /* Original first byte past end of target, before edit */
4150 u32 iTEnd; /* Current first byte past end of target */
drh5026ddb2023-11-28 12:28:284151 u8 eTLabel; /* Node type of the target label */
drh5ec9c912023-12-02 01:06:334152 u32 iTLabel = 0; /* Index of the label */
4153 u32 nTLabel = 0; /* Header size in bytes for the target label */
drh8f8d4812023-12-02 20:37:454154 u32 szTLabel = 0; /* Size of the target label payload */
drh5ec9c912023-12-02 01:06:334155 u32 iTValue = 0; /* Index of the target value */
4156 u32 nTValue = 0; /* Header size of the target value */
drh8f8d4812023-12-02 20:37:454157 u32 szTValue = 0; /* Payload size for the target value */
drheb04a0b2023-11-27 23:46:124158
4159 u32 iPCursor; /* Cursor position while scanning the patch */
4160 u32 iPEnd; /* First byte past the end of the patch */
drh5026ddb2023-11-28 12:28:284161 u8 ePLabel; /* Node type of the patch label */
drheb04a0b2023-11-27 23:46:124162 u32 iPLabel; /* Start of patch label */
4163 u32 nPLabel; /* Size of header on the patch label */
4164 u32 szPLabel; /* Payload size of the patch label */
4165 u32 iPValue; /* Start of patch value */
4166 u32 nPValue; /* Header size for the patch value */
4167 u32 szPValue; /* Payload size of the patch value */
4168
4169 assert( iTarget>=0 && iTarget<pTarget->nBlob );
4170 assert( iPatch>=0 && iPatch<pPatch->nBlob );
4171 x = pPatch->aBlob[iPatch] & 0x0f;
4172 if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */
4173 u32 szPatch; /* Total size of the patch, header+payload */
4174 u32 szTarget; /* Total size of the target, header+payload */
4175 n = jsonbPayloadSize(pPatch, iPatch, &sz);
4176 szPatch = n+sz;
4177 sz = 0;
4178 n = jsonbPayloadSize(pTarget, iTarget, &sz);
4179 szTarget = n+sz;
4180 jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch);
4181 return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */
4182 }
4183 x = pTarget->aBlob[iTarget] & 0x0f;
4184 if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */
drheb04a0b2023-11-27 23:46:124185 n = jsonbPayloadSize(pTarget, iTarget, &sz);
drhda257832023-11-29 17:36:544186 jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0);
4187 x = pTarget->aBlob[iTarget];
4188 pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT;
drheb04a0b2023-11-27 23:46:124189 }
4190 n = jsonbPayloadSize(pPatch, iPatch, &sz);
drhae2e9722023-12-05 00:17:174191 if( NEVER(n==0) ) return JSON_MERGE_BADPATCH;
drheb04a0b2023-11-27 23:46:124192 iPCursor = iPatch+n;
4193 iPEnd = iPCursor+sz;
4194 n = jsonbPayloadSize(pTarget, iTarget, &sz);
drhae2e9722023-12-05 00:17:174195 if( NEVER(n==0) ) return JSON_MERGE_BADTARGET;
drheb04a0b2023-11-27 23:46:124196 iTStart = iTarget+n;
4197 iTEndBE = iTStart+sz;
4198
4199 while( iPCursor<iPEnd ){ /* Algorithm line 07 */
4200 iPLabel = iPCursor;
drh5026ddb2023-11-28 12:28:284201 ePLabel = pPatch->aBlob[iPCursor] & 0x0f;
4202 if( ePLabel<JSONB_TEXT || ePLabel>JSONB_TEXTRAW ){
4203 return JSON_MERGE_BADPATCH;
4204 }
drheb04a0b2023-11-27 23:46:124205 nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel);
4206 if( nPLabel==0 ) return JSON_MERGE_BADPATCH;
4207 iPValue = iPCursor + nPLabel + szPLabel;
drhae2e9722023-12-05 00:17:174208 if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH;
drheb04a0b2023-11-27 23:46:124209 nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue);
4210 if( nPValue==0 ) return JSON_MERGE_BADPATCH;
4211 iPCursor = iPValue + nPValue + szPValue;
4212 if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH;
4213
4214 iTCursor = iTStart;
4215 iTEnd = iTEndBE + pTarget->delta;
4216 while( iTCursor<iTEnd ){
drh91ec00c2023-12-06 14:50:484217 int isEqual; /* true if the patch and target labels match */
drheb04a0b2023-11-27 23:46:124218 iTLabel = iTCursor;
drh5026ddb2023-11-28 12:28:284219 eTLabel = pTarget->aBlob[iTCursor] & 0x0f;
4220 if( eTLabel<JSONB_TEXT || eTLabel>JSONB_TEXTRAW ){
4221 return JSON_MERGE_BADTARGET;
4222 }
drheb04a0b2023-11-27 23:46:124223 nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel);
4224 if( nTLabel==0 ) return JSON_MERGE_BADTARGET;
4225 iTValue = iTLabel + nTLabel + szTLabel;
4226 if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET;
4227 nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue);
4228 if( nTValue==0 ) return JSON_MERGE_BADTARGET;
4229 if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET;
drh91ec00c2023-12-06 14:50:484230 isEqual = jsonLabelCompare(
4231 (const char*)&pPatch->aBlob[iPLabel+nPLabel],
4232 szPLabel,
4233 (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW),
4234 (const char*)&pTarget->aBlob[iTLabel+nTLabel],
4235 szTLabel,
4236 (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW));
4237 if( isEqual ) break;
drheb04a0b2023-11-27 23:46:124238 iTCursor = iTValue + nTValue + szTValue;
4239 }
4240 x = pPatch->aBlob[iPValue] & 0x0f;
4241 if( iTCursor<iTEnd ){
4242 /* A match was found. Algorithm line 08 */
4243 if( x==0 ){
4244 /* Patch value is NULL. Algorithm line 09 */
drhae2e9722023-12-05 00:17:174245 jsonBlobEdit(pTarget, iTLabel, nTLabel+szTLabel+nTValue+szTValue, 0,0);
4246 /* vvvvvv----- No OOM on a delete-only edit */
4247 if( NEVER(pTarget->oom) ) return JSON_MERGE_OOM;
drheb04a0b2023-11-27 23:46:124248 }else{
4249 /* Algorithm line 12 */
drhec1f59f2023-11-28 13:35:534250 int rc, savedDelta = pTarget->delta;
4251 pTarget->delta = 0;
drh3cdb0792023-12-04 23:12:574252 rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue);
drheb04a0b2023-11-27 23:46:124253 if( rc ) return rc;
drhec1f59f2023-11-28 13:35:534254 pTarget->delta += savedDelta;
drheb04a0b2023-11-27 23:46:124255 }
4256 }else if( x>0 ){ /* Algorithm line 13 */
4257 /* No match and patch value is not NULL */
drhec1f59f2023-11-28 13:35:534258 u32 szNew = szPLabel+nPLabel;
drh5026ddb2023-11-28 12:28:284259 if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */
drhec1f59f2023-11-28 13:35:534260 jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew);
drhf46f89d2023-11-28 00:27:584261 if( pTarget->oom ) return JSON_MERGE_OOM;
drhec1f59f2023-11-28 13:35:534262 memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew);
4263 memcpy(&pTarget->aBlob[iTEnd+szNew],
4264 &pPatch->aBlob[iPValue], szPValue+nPValue);
drhf46f89d2023-11-28 00:27:584265 }else{
drhec1f59f2023-11-28 13:35:534266 int rc, savedDelta;
drhf46f89d2023-11-28 00:27:584267 jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1);
4268 if( pTarget->oom ) return JSON_MERGE_OOM;
4269 memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew);
4270 pTarget->aBlob[iTEnd+szNew] = 0x00;
drhec1f59f2023-11-28 13:35:534271 savedDelta = pTarget->delta;
4272 pTarget->delta = 0;
drh3cdb0792023-12-04 23:12:574273 rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue);
drhf46f89d2023-11-28 00:27:584274 if( rc ) return rc;
drhec1f59f2023-11-28 13:35:534275 pTarget->delta += savedDelta;
drhf46f89d2023-11-28 00:27:584276 }
drheb04a0b2023-11-27 23:46:124277 }
4278 }
drhda257832023-11-29 17:36:544279 if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget);
drheb04a0b2023-11-27 23:46:124280 return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK;
4281}
drheb04a0b2023-11-27 23:46:124282
4283
drh633647a2017-03-22 21:24:314284/*
4285** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
4286** object that is the result of running the RFC 7396 MergePatch() algorithm
4287** on the two arguments.
4288*/
drh37f03df2017-03-23 20:33:494289static void jsonPatchFunc(
drh633647a2017-03-22 21:24:314290 sqlite3_context *ctx,
4291 int argc,
4292 sqlite3_value **argv
4293){
drhda257832023-11-29 17:36:544294 JsonParse *pTarget; /* The TARGET */
4295 JsonParse *pPatch; /* The PATCH */
4296 int rc; /* Result code */
drh633647a2017-03-22 21:24:314297
drh9dbf96b2022-01-06 01:40:094298 UNUSED_PARAMETER(argc);
drhda257832023-11-29 17:36:544299 assert( argc==2 );
4300 pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE);
4301 if( pTarget==0 ) return;
4302 pPatch = jsonParseFuncArg(ctx, argv[1], 0);
4303 if( pPatch ){
drh3cdb0792023-12-04 23:12:574304 rc = jsonMergePatch(pTarget, 0, pPatch, 0);
drhda257832023-11-29 17:36:544305 if( rc==JSON_MERGE_OK ){
4306 jsonReturnParse(ctx, pTarget);
4307 }else if( rc==JSON_MERGE_OOM ){
4308 sqlite3_result_error_nomem(ctx);
drh5026ddb2023-11-28 12:28:284309 }else{
drhda257832023-11-29 17:36:544310 sqlite3_result_error(ctx, "malformed JSON", -1);
drh5026ddb2023-11-28 12:28:284311 }
drhda257832023-11-29 17:36:544312 jsonParseFree(pPatch);
drh5026ddb2023-11-28 12:28:284313 }
drhda257832023-11-29 17:36:544314 jsonParseFree(pTarget);
drh633647a2017-03-22 21:24:314315}
4316
4317
drh987eb1f2015-08-17 15:17:374318/*
4319** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
4320** object that contains all name/value given in arguments. Or if any name
4321** is not a string or if any value is a BLOB, throw an error.
4322*/
4323static void jsonObjectFunc(
drhbc8f0922015-08-22 19:39:044324 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:374325 int argc,
4326 sqlite3_value **argv
4327){
4328 int i;
drh505ad2c2015-08-21 17:33:114329 JsonString jx;
drh987eb1f2015-08-17 15:17:374330 const char *z;
4331 u32 n;
4332
4333 if( argc&1 ){
drhbc8f0922015-08-22 19:39:044334 sqlite3_result_error(ctx, "json_object() requires an even number "
drh987eb1f2015-08-17 15:17:374335 "of arguments", -1);
4336 return;
4337 }
drhae5f55e2023-09-29 12:45:144338 jsonStringInit(&jx, ctx);
drhd0960592015-08-17 21:22:324339 jsonAppendChar(&jx, '{');
drh987eb1f2015-08-17 15:17:374340 for(i=0; i<argc; i+=2){
drh987eb1f2015-08-17 15:17:374341 if( sqlite3_value_type(argv[i])!=SQLITE_TEXT ){
drhbc8f0922015-08-22 19:39:044342 sqlite3_result_error(ctx, "json_object() labels must be TEXT", -1);
drhae5f55e2023-09-29 12:45:144343 jsonStringReset(&jx);
drh987eb1f2015-08-17 15:17:374344 return;
4345 }
drhd0960592015-08-17 21:22:324346 jsonAppendSeparator(&jx);
drh987eb1f2015-08-17 15:17:374347 z = (const char*)sqlite3_value_text(argv[i]);
drhb7fd9512023-12-04 00:31:584348 n = sqlite3_value_bytes(argv[i]);
drh987eb1f2015-08-17 15:17:374349 jsonAppendString(&jx, z, n);
drhd0960592015-08-17 21:22:324350 jsonAppendChar(&jx, ':');
drhae5f55e2023-09-29 12:45:144351 jsonAppendSqlValue(&jx, argv[i+1]);
drh987eb1f2015-08-17 15:17:374352 }
drhd0960592015-08-17 21:22:324353 jsonAppendChar(&jx, '}');
drhca1ce772023-12-01 12:57:124354 jsonReturnString(&jx, 0, 0);
drhf5ddb9c2015-09-11 00:06:414355 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
drh987eb1f2015-08-17 15:17:374356}
4357
4358
4359/*
drh301eecc2015-08-17 20:14:194360** json_remove(JSON, PATH, ...)
4361**
drh3ad93bb2015-08-29 19:41:454362** Remove the named elements from JSON and return the result. malformed
4363** JSON or PATH arguments result in an error.
drh301eecc2015-08-17 20:14:194364*/
4365static void jsonRemoveFunc(
drhbc8f0922015-08-22 19:39:044366 sqlite3_context *ctx,
drh301eecc2015-08-17 20:14:194367 int argc,
4368 sqlite3_value **argv
4369){
drhef97f832023-11-28 18:16:024370 JsonParse *p; /* The parse */
4371 const char *zPath = 0; /* Path of element to be removed */
drh53c21602023-12-02 18:17:384372 int i; /* Loop counter */
4373 u32 rc; /* Subroutine return code */
drh301eecc2015-08-17 20:14:194374
4375 if( argc<1 ) return;
drh0b8b1c32023-12-04 19:14:134376 p = jsonParseFuncArg(ctx, argv[0], argc>1 ? JSON_EDITABLE : 0);
drhef97f832023-11-28 18:16:024377 if( p==0 ) return;
4378 for(i=1; i<argc; i++){
drhef97f832023-11-28 18:16:024379 zPath = (const char*)sqlite3_value_text(argv[i]);
4380 if( zPath==0 ){
drh9c794b92023-12-04 17:40:284381 goto json_remove_done;
drhef97f832023-11-28 18:16:024382 }
4383 if( zPath[0]!='$' ){
4384 goto json_remove_patherror;
4385 }
4386 if( zPath[1]==0 ){
4387 /* json_remove(j,'$') returns NULL */
drh9c794b92023-12-04 17:40:284388 goto json_remove_done;
drhef97f832023-11-28 18:16:024389 }
4390 p->eEdit = JEDIT_DEL;
4391 p->delta = 0;
drh53c21602023-12-02 18:17:384392 rc = jsonLookupStep(p, 0, zPath+1, 0);
drh9c794b92023-12-04 17:40:284393 if( JSON_LOOKUP_ISERROR(rc) ){
4394 if( rc==JSON_LOOKUP_NOTFOUND ){
4395 continue; /* No-op */
4396 }else if( rc==JSON_LOOKUP_PATHERROR ){
4397 jsonBadPathError(ctx, zPath);
4398 }else{
4399 sqlite3_result_error(ctx, "malformed JSON", -1);
4400 }
4401 goto json_remove_done;
4402 }
drha8f39a92015-09-21 22:53:164403 }
drhef97f832023-11-28 18:16:024404 jsonReturnParse(ctx, p);
4405 jsonParseFree(p);
4406 return;
4407
4408json_remove_patherror:
drheb18ae32023-12-03 00:51:304409 jsonBadPathError(ctx, zPath);
drhef97f832023-11-28 18:16:024410
drh9c794b92023-12-04 17:40:284411json_remove_done:
drhef97f832023-11-28 18:16:024412 jsonParseFree(p);
4413 return;
drhd0960592015-08-17 21:22:324414}
4415
4416/*
4417** json_replace(JSON, PATH, VALUE, ...)
4418**
4419** Replace the value at PATH with VALUE. If PATH does not already exist,
drh3ad93bb2015-08-29 19:41:454420** this routine is a no-op. If JSON or PATH is malformed, throw an error.
drhd0960592015-08-17 21:22:324421*/
4422static void jsonReplaceFunc(
drhbc8f0922015-08-22 19:39:044423 sqlite3_context *ctx,
drhd0960592015-08-17 21:22:324424 int argc,
4425 sqlite3_value **argv
4426){
drhd0960592015-08-17 21:22:324427 if( argc<1 ) return;
4428 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:044429 jsonWrongNumArgs(ctx, "replace");
drhd0960592015-08-17 21:22:324430 return;
4431 }
drhbfc7e622023-11-30 00:52:334432 jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL);
drh301eecc2015-08-17 20:14:194433}
drh505ad2c2015-08-21 17:33:114434
drhdc60c682022-01-08 15:05:534435
drh52216ad2015-08-18 02:28:034436/*
4437** json_set(JSON, PATH, VALUE, ...)
4438**
4439** Set the value at PATH to VALUE. Create the PATH if it does not already
4440** exist. Overwrite existing values that do exist.
drh3ad93bb2015-08-29 19:41:454441** If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:034442**
4443** json_insert(JSON, PATH, VALUE, ...)
4444**
4445** Create PATH and initialize it to VALUE. If PATH already exists, this
drh3ad93bb2015-08-29 19:41:454446** routine is a no-op. If JSON or PATH is malformed, throw an error.
drh52216ad2015-08-18 02:28:034447*/
4448static void jsonSetFunc(
drhbc8f0922015-08-22 19:39:044449 sqlite3_context *ctx,
drh52216ad2015-08-18 02:28:034450 int argc,
4451 sqlite3_value **argv
4452){
drhbfc7e622023-11-30 00:52:334453
drhe5c384e2023-10-02 20:16:064454 int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
4455 int bIsSet = (flags&JSON_ISSET)!=0;
drh52216ad2015-08-18 02:28:034456
4457 if( argc<1 ) return;
4458 if( (argc&1)==0 ) {
drhbc8f0922015-08-22 19:39:044459 jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert");
drh52216ad2015-08-18 02:28:034460 return;
4461 }
drhbfc7e622023-11-30 00:52:334462 jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS);
drh52216ad2015-08-18 02:28:034463}
drh301eecc2015-08-17 20:14:194464
4465/*
drh987eb1f2015-08-17 15:17:374466** json_type(JSON)
4467** json_type(JSON, PATH)
4468**
drha4e4e182022-01-07 16:03:004469** Return the top-level "type" of a JSON string. json_type() raises an
drha6c596b2022-01-11 22:06:254470** error if either the JSON or PATH inputs are not well-formed.
drh987eb1f2015-08-17 15:17:374471*/
4472static void jsonTypeFunc(
drhbc8f0922015-08-22 19:39:044473 sqlite3_context *ctx,
drh987eb1f2015-08-17 15:17:374474 int argc,
4475 sqlite3_value **argv
4476){
drhe35fc302018-08-30 01:52:104477 JsonParse *p; /* The parse */
drh276042b2023-11-30 19:29:564478 const char *zPath = 0;
4479 u32 i;
drh987eb1f2015-08-17 15:17:374480
drh276042b2023-11-30 19:29:564481 p = jsonParseFuncArg(ctx, argv[0], 0);
drhe35fc302018-08-30 01:52:104482 if( p==0 ) return;
drha8f39a92015-09-21 22:53:164483 if( argc==2 ){
4484 zPath = (const char*)sqlite3_value_text(argv[1]);
drh9c794b92023-12-04 17:40:284485 if( zPath==0 ) goto json_type_done;
drh276042b2023-11-30 19:29:564486 if( zPath[0]!='$' ){
4487 jsonBadPathError(ctx, zPath);
4488 goto json_type_done;
4489 }
drh53c21602023-12-02 18:17:384490 i = jsonLookupStep(p, 0, zPath+1, 0);
4491 if( JSON_LOOKUP_ISERROR(i) ){
4492 if( i==JSON_LOOKUP_NOTFOUND ){
drh276042b2023-11-30 19:29:564493 /* no-op */
drh53c21602023-12-02 18:17:384494 }else if( i==JSON_LOOKUP_PATHERROR ){
drh276042b2023-11-30 19:29:564495 jsonBadPathError(ctx, zPath);
4496 }else{
4497 sqlite3_result_error(ctx, "malformed JSON", -1);
4498 }
4499 goto json_type_done;
4500 }
drha8f39a92015-09-21 22:53:164501 }else{
drh276042b2023-11-30 19:29:564502 i = 0;
drha8f39a92015-09-21 22:53:164503 }
drh276042b2023-11-30 19:29:564504 sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC);
4505json_type_done:
4506 jsonParseFree(p);
drh987eb1f2015-08-17 15:17:374507}
drh5634cc02015-08-17 11:28:034508
drhbc8f0922015-08-22 19:39:044509/*
drhb4e7d592024-03-06 14:30:424510** json_pretty(JSON)
4511** json_pretty(JSON, INDENT)
4512**
4513** Return text that is a pretty-printed rendering of the input JSON.
4514** If the argument is not valid JSON, return NULL.
4515**
4516** The INDENT argument is text that is used for indentation. If omitted,
4517** it defaults to four spaces (the same as PostgreSQL).
4518*/
4519static void jsonPrettyFunc(
4520 sqlite3_context *ctx,
4521 int argc,
4522 sqlite3_value **argv
4523){
4524 JsonString s; /* The output string */
4525 JsonPretty x; /* Pretty printing context */
4526
4527 memset(&x, 0, sizeof(x));
4528 x.pParse = jsonParseFuncArg(ctx, argv[0], 0);
4529 if( x.pParse==0 ) return;
4530 x.pOut = &s;
4531 jsonStringInit(&s, ctx);
4532 if( argc==1 || (x.zIndent = (const char*)sqlite3_value_text(argv[1]))==0 ){
4533 x.zIndent = " ";
4534 x.szIndent = 4;
4535 }else{
4536 x.szIndent = (u32)strlen(x.zIndent);
4537 }
4538 jsonTranslateBlobToPrettyText(&x, 0);
4539 jsonReturnString(&s, 0, 0);
4540 jsonParseFree(x.pParse);
4541}
4542
4543/*
drhbc8f0922015-08-22 19:39:044544** json_valid(JSON)
drh821a4c92023-11-27 15:57:114545** json_valid(JSON, FLAGS)
drhbc8f0922015-08-22 19:39:044546**
drh821a4c92023-11-27 15:57:114547** Check the JSON argument to see if it is well-formed. The FLAGS argument
4548** encodes the various constraints on what is meant by "well-formed":
drh5b6cfb72023-10-05 18:09:124549**
drh821a4c92023-11-27 15:57:114550** 0x01 Canonical RFC-8259 JSON text
4551** 0x02 JSON text with optional JSON-5 extensions
4552** 0x04 Superficially appears to be JSONB
4553** 0x08 Strictly well-formed JSONB
drh5b6cfb72023-10-05 18:09:124554**
drh821a4c92023-11-27 15:57:114555** If the FLAGS argument is omitted, it defaults to 1. Useful values for
4556** FLAGS include:
drh5b6cfb72023-10-05 18:09:124557**
drh821a4c92023-11-27 15:57:114558** 1 Strict canonical JSON text
4559** 2 JSON text perhaps with JSON-5 extensions
4560** 4 Superficially appears to be JSONB
4561** 5 Canonical JSON text or superficial JSONB
4562** 6 JSON-5 text or superficial JSONB
4563** 8 Strict JSONB
4564** 9 Canonical JSON text or strict JSONB
4565** 10 JSON-5 text or strict JSONB
4566**
4567** Other flag combinations are redundant. For example, every canonical
4568** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3
4569** are the same. Similarly, any input that passes a strict JSONB validation
4570** will also pass the superficial validation so 12 through 15 are the same
4571** as 8 through 11 respectively.
4572**
4573** This routine runs in linear time to validate text and when doing strict
4574** JSONB validation. Superficial JSONB validation is constant time,
4575** assuming the BLOB is already in memory. The performance advantage
4576** of superficial JSONB validation is why that option is provided.
4577** Application developers can choose to do fast superficial validation or
4578** slower strict validation, according to their specific needs.
4579**
4580** Only the lower four bits of the FLAGS argument are currently used.
4581** Higher bits are reserved for future expansion. To facilitate
4582** compatibility, the current implementation raises an error if any bit
4583** in FLAGS is set other than the lower four bits.
4584**
4585** The original circa 2015 implementation of the JSON routines in
4586** SQLite only supported canonical RFC-8259 JSON text and the json_valid()
4587** function only accepted one argument. That is why the default value
4588** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only
4589** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS
4590** argument was added when the JSON routines were extended to support
4591** JSON5-like extensions and binary JSONB stored in BLOBs.
4592**
4593** Return Values:
4594**
4595** * Raise an error if FLAGS is outside the range of 1 to 15.
4596** * Return NULL if the input is NULL
4597** * Return 1 if the input is well-formed.
4598** * Return 0 if the input is not well-formed.
drhbc8f0922015-08-22 19:39:044599*/
4600static void jsonValidFunc(
4601 sqlite3_context *ctx,
4602 int argc,
4603 sqlite3_value **argv
4604){
drhe35fc302018-08-30 01:52:104605 JsonParse *p; /* The parse */
drh821a4c92023-11-27 15:57:114606 u8 flags = 1;
4607 u8 res = 0;
4608 if( argc==2 ){
4609 i64 f = sqlite3_value_int64(argv[1]);
4610 if( f<1 || f>15 ){
4611 sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be"
4612 " between 1 and 15", -1);
4613 return;
4614 }
4615 flags = f & 0x0f;
4616 }
4617 switch( sqlite3_value_type(argv[0]) ){
4618 case SQLITE_NULL: {
drh91c00922023-08-11 11:12:464619#ifdef SQLITE_LEGACY_JSON_VALID
drh821a4c92023-11-27 15:57:114620 /* Incorrect legacy behavior was to return FALSE for a NULL input */
4621 sqlite3_result_int(ctx, 0);
drh91c00922023-08-11 11:12:464622#endif
drh821a4c92023-11-27 15:57:114623 return;
4624 }
4625 case SQLITE_BLOB: {
drhcbe4a262025-04-21 19:53:124626 JsonParse py;
4627 memset(&py, 0, sizeof(py));
4628 if( jsonArgIsJsonb(argv[0], &py) ){
drh81cde802025-04-21 20:58:494629 if( flags & 0x04 ){
drhce46e0e2023-12-11 14:01:384630 /* Superficial checking only - accomplished by the
drhcbe4a262025-04-21 19:53:124631 ** jsonArgIsJsonb() call above. */
drhc78c3c92023-12-02 21:39:344632 res = 1;
drhe318f102024-01-23 13:21:404633 }else if( flags & 0x08 ){
drhc78c3c92023-12-02 21:39:344634 /* Strict checking. Check by translating BLOB->TEXT->BLOB. If
4635 ** no errors occur, call that a "strict check". */
drhcbe4a262025-04-21 19:53:124636 res = 0==jsonbValidityCheck(&py, 0, py.nBlob, 1);
drhc78c3c92023-12-02 21:39:344637 }
drhe318f102024-01-23 13:21:404638 break;
drh821a4c92023-11-27 15:57:114639 }
drhe318f102024-01-23 13:21:404640 /* Fall through into interpreting the input as text. See note
drh6bb8ce62024-01-23 13:28:214641 ** above at tag-20240123-a. */
drhe318f102024-01-23 13:21:404642 /* no break */ deliberate_fall_through
drh821a4c92023-11-27 15:57:114643 }
4644 default: {
drh38aeb972023-11-30 20:57:484645 JsonParse px;
drh821a4c92023-11-27 15:57:114646 if( (flags & 0x3)==0 ) break;
drh38aeb972023-11-30 20:57:484647 memset(&px, 0, sizeof(px));
4648
4649 p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR);
4650 if( p ){
4651 if( p->oom ){
4652 sqlite3_result_error_nomem(ctx);
4653 }else if( p->nErr ){
4654 /* no-op */
drh4b9ed1b2023-11-30 23:36:144655 }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){
drh38aeb972023-11-30 20:57:484656 res = 1;
4657 }
drh821a4c92023-11-27 15:57:114658 jsonParseFree(p);
drh38aeb972023-11-30 20:57:484659 }else{
4660 sqlite3_result_error_nomem(ctx);
drh821a4c92023-11-27 15:57:114661 }
4662 break;
4663 }
drh91c00922023-08-11 11:12:464664 }
drh821a4c92023-11-27 15:57:114665 sqlite3_result_int(ctx, res);
drh058f3db2023-04-25 21:24:204666}
drh272ae622023-04-28 14:48:114667
drh272ae622023-04-28 14:48:114668/*
drh7be14732023-04-30 19:34:414669** json_error_position(JSON)
drh272ae622023-04-28 14:48:114670**
drh4b9ed1b2023-11-30 23:36:144671** If the argument is NULL, return NULL
drh272ae622023-04-28 14:48:114672**
drh5a890b42023-12-11 20:44:214673** If the argument is BLOB, do a full validity check and return non-zero
4674** if the check fails. The return value is the approximate 1-based offset
4675** to the byte of the element that contains the first error.
drh9c794b92023-12-04 17:40:284676**
4677** Otherwise interpret the argument is TEXT (even if it is numeric) and
drh4b9ed1b2023-11-30 23:36:144678** return the 1-based character position for where the parser first recognized
4679** that the input was not valid JSON, or return 0 if the input text looks
4680** ok. JSON-5 extensions are accepted.
drh272ae622023-04-28 14:48:114681*/
4682static void jsonErrorFunc(
4683 sqlite3_context *ctx,
4684 int argc,
4685 sqlite3_value **argv
4686){
drh694beec2023-11-29 20:06:494687 i64 iErrPos = 0; /* Error position to be returned */
4688 JsonParse s;
4689
4690 assert( argc==1 );
drh272ae622023-04-28 14:48:114691 UNUSED_PARAMETER(argc);
drh9c794b92023-12-04 17:40:284692 memset(&s, 0, sizeof(s));
drh4093b292024-01-03 16:41:504693 s.db = sqlite3_context_db_handle(ctx);
drhcbe4a262025-04-21 19:53:124694 if( jsonArgIsJsonb(argv[0], &s) ){
drh87399a52023-12-12 14:33:524695 iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1);
drh9c794b92023-12-04 17:40:284696 }else{
4697 s.zJson = (char*)sqlite3_value_text(argv[0]);
4698 if( s.zJson==0 ) return; /* NULL input or OOM */
4699 s.nJson = sqlite3_value_bytes(argv[0]);
4700 if( jsonConvertTextToBlob(&s,0) ){
4701 if( s.oom ){
4702 iErrPos = -1;
4703 }else{
drh694beec2023-11-29 20:06:494704 /* Convert byte-offset s.iErr into a character offset */
drh9c794b92023-12-04 17:40:284705 u32 k;
drhfa43e212023-12-05 01:44:154706 assert( s.zJson!=0 ); /* Because s.oom is false */
drh744581d2024-01-31 15:20:134707 for(k=0; k<s.iErr && ALWAYS(s.zJson[k]); k++){
drh694beec2023-11-29 20:06:494708 if( (s.zJson[k] & 0xc0)!=0x80 ) iErrPos++;
4709 }
4710 iErrPos++;
4711 }
drh694beec2023-11-29 20:06:494712 }
drh272ae622023-04-28 14:48:114713 }
drh9c794b92023-12-04 17:40:284714 jsonParseReset(&s);
4715 if( iErrPos<0 ){
4716 sqlite3_result_error_nomem(ctx);
4717 }else{
4718 sqlite3_result_int64(ctx, iErrPos);
4719 }
drhbc8f0922015-08-22 19:39:044720}
4721
drhff135ae2015-12-30 01:07:024722/****************************************************************************
4723** Aggregate SQL function implementations
4724****************************************************************************/
4725/*
4726** json_group_array(VALUE)
4727**
4728** Return a JSON array composed of all values in the aggregate.
4729*/
4730static void jsonArrayStep(
4731 sqlite3_context *ctx,
4732 int argc,
4733 sqlite3_value **argv
4734){
4735 JsonString *pStr;
drh9dbf96b2022-01-06 01:40:094736 UNUSED_PARAMETER(argc);
drhff135ae2015-12-30 01:07:024737 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
4738 if( pStr ){
4739 if( pStr->zBuf==0 ){
drhae5f55e2023-09-29 12:45:144740 jsonStringInit(pStr, ctx);
drhff135ae2015-12-30 01:07:024741 jsonAppendChar(pStr, '[');
drhfab5b072019-09-14 00:21:344742 }else if( pStr->nUsed>1 ){
drhff135ae2015-12-30 01:07:024743 jsonAppendChar(pStr, ',');
drhff135ae2015-12-30 01:07:024744 }
dan8505d732021-04-14 12:11:394745 pStr->pCtx = ctx;
drhae5f55e2023-09-29 12:45:144746 jsonAppendSqlValue(pStr, argv[0]);
drhff135ae2015-12-30 01:07:024747 }
4748}
drh8be47a72018-07-05 20:05:294749static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
drhff135ae2015-12-30 01:07:024750 JsonString *pStr;
4751 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
4752 if( pStr ){
drh7e86d3f2023-09-30 14:34:394753 int flags;
drhff135ae2015-12-30 01:07:024754 pStr->pCtx = ctx;
4755 jsonAppendChar(pStr, ']');
drh7e86d3f2023-09-30 14:34:394756 flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
drhe1e2f2d2023-10-06 14:52:494757 if( pStr->eErr ){
drhca1ce772023-12-01 12:57:124758 jsonReturnString(pStr, 0, 0);
drhe1e2f2d2023-10-06 14:52:494759 return;
drh7e86d3f2023-09-30 14:34:394760 }else if( flags & JSON_BLOB ){
4761 jsonReturnStringAsBlob(pStr);
drh4500d872023-10-03 22:40:224762 if( isFinal ){
drh2a27be22023-12-08 14:54:224763 if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
drh4500d872023-10-03 22:40:224764 }else{
drh777a0882024-01-20 12:13:004765 jsonStringTrimOneChar(pStr);
drh4500d872023-10-03 22:40:224766 }
drh7e86d3f2023-09-30 14:34:394767 return;
drh8be47a72018-07-05 20:05:294768 }else if( isFinal ){
mistachkined008ec2018-09-12 01:05:264769 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
drhf02cc9a2023-07-25 15:08:184770 pStr->bStatic ? SQLITE_TRANSIENT :
drh43dc31c2023-10-17 19:33:524771 sqlite3RCStrUnref);
drhff135ae2015-12-30 01:07:024772 pStr->bStatic = 1;
drh8be47a72018-07-05 20:05:294773 }else{
mistachkined008ec2018-09-12 01:05:264774 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
drh777a0882024-01-20 12:13:004775 jsonStringTrimOneChar(pStr);
drhff135ae2015-12-30 01:07:024776 }
4777 }else{
4778 sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC);
4779 }
4780 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
4781}
drh8be47a72018-07-05 20:05:294782static void jsonArrayValue(sqlite3_context *ctx){
4783 jsonArrayCompute(ctx, 0);
4784}
4785static void jsonArrayFinal(sqlite3_context *ctx){
4786 jsonArrayCompute(ctx, 1);
4787}
4788
4789#ifndef SQLITE_OMIT_WINDOWFUNC
4790/*
4791** This method works for both json_group_array() and json_group_object().
4792** It works by removing the first element of the group by searching forward
4793** to the first comma (",") that is not within a string and deleting all
4794** text through that comma.
4795*/
4796static void jsonGroupInverse(
4797 sqlite3_context *ctx,
4798 int argc,
4799 sqlite3_value **argv
4800){
drhe39f3882019-09-21 17:31:034801 unsigned int i;
drh8be47a72018-07-05 20:05:294802 int inStr = 0;
drhfab5b072019-09-14 00:21:344803 int nNest = 0;
drh8be47a72018-07-05 20:05:294804 char *z;
drhfab5b072019-09-14 00:21:344805 char c;
drh8be47a72018-07-05 20:05:294806 JsonString *pStr;
drh9dbf96b2022-01-06 01:40:094807 UNUSED_PARAMETER(argc);
4808 UNUSED_PARAMETER(argv);
drh8be47a72018-07-05 20:05:294809 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
drh491d4c82018-07-07 20:23:464810#ifdef NEVER
drhfd4b7282018-07-07 19:47:214811 /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will
larrybr55be2162023-06-07 17:03:224812 ** always have been called to initialize it */
drhfd4b7282018-07-07 19:47:214813 if( NEVER(!pStr) ) return;
drh491d4c82018-07-07 20:23:464814#endif
drh8be47a72018-07-05 20:05:294815 z = pStr->zBuf;
drh0e5cd342021-04-13 01:12:324816 for(i=1; i<pStr->nUsed && ((c = z[i])!=',' || inStr || nNest); i++){
drhfab5b072019-09-14 00:21:344817 if( c=='"' ){
drh8be47a72018-07-05 20:05:294818 inStr = !inStr;
drhfab5b072019-09-14 00:21:344819 }else if( c=='\\' ){
drh8be47a72018-07-05 20:05:294820 i++;
drhfab5b072019-09-14 00:21:344821 }else if( !inStr ){
4822 if( c=='{' || c=='[' ) nNest++;
4823 if( c=='}' || c==']' ) nNest--;
drh8be47a72018-07-05 20:05:294824 }
4825 }
drh0e5cd342021-04-13 01:12:324826 if( i<pStr->nUsed ){
4827 pStr->nUsed -= i;
4828 memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1);
4829 z[pStr->nUsed] = 0;
4830 }else{
4831 pStr->nUsed = 1;
4832 }
drh8be47a72018-07-05 20:05:294833}
4834#else
4835# define jsonGroupInverse 0
4836#endif
4837
drhff135ae2015-12-30 01:07:024838
4839/*
4840** json_group_obj(NAME,VALUE)
4841**
4842** Return a JSON object composed of all names and values in the aggregate.
4843*/
4844static void jsonObjectStep(
4845 sqlite3_context *ctx,
4846 int argc,
4847 sqlite3_value **argv
4848){
4849 JsonString *pStr;
4850 const char *z;
4851 u32 n;
drh9dbf96b2022-01-06 01:40:094852 UNUSED_PARAMETER(argc);
drhff135ae2015-12-30 01:07:024853 pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
4854 if( pStr ){
drha01b7ad2025-05-24 20:20:204855 z = (const char*)sqlite3_value_text(argv[0]);
4856 n = sqlite3Strlen30(z);
drhff135ae2015-12-30 01:07:024857 if( pStr->zBuf==0 ){
drhae5f55e2023-09-29 12:45:144858 jsonStringInit(pStr, ctx);
drhff135ae2015-12-30 01:07:024859 jsonAppendChar(pStr, '{');
drha01b7ad2025-05-24 20:20:204860 }else if( pStr->nUsed>1 && z!=0 ){
drhff135ae2015-12-30 01:07:024861 jsonAppendChar(pStr, ',');
drhff135ae2015-12-30 01:07:024862 }
drhd2f55772021-05-28 12:15:194863 pStr->pCtx = ctx;
drha01b7ad2025-05-24 20:20:204864 if( z!=0 ){
4865 jsonAppendString(pStr, z, n);
4866 jsonAppendChar(pStr, ':');
4867 jsonAppendSqlValue(pStr, argv[1]);
4868 }
drhff135ae2015-12-30 01:07:024869 }
4870}
drh8be47a72018-07-05 20:05:294871static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
drhff135ae2015-12-30 01:07:024872 JsonString *pStr;
4873 pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
4874 if( pStr ){
drh7e86d3f2023-09-30 14:34:394875 int flags;
drhff135ae2015-12-30 01:07:024876 jsonAppendChar(pStr, '}');
drh7e86d3f2023-09-30 14:34:394877 pStr->pCtx = ctx;
4878 flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
drhe1e2f2d2023-10-06 14:52:494879 if( pStr->eErr ){
drhca1ce772023-12-01 12:57:124880 jsonReturnString(pStr, 0, 0);
drhe1e2f2d2023-10-06 14:52:494881 return;
drh7e86d3f2023-09-30 14:34:394882 }else if( flags & JSON_BLOB ){
4883 jsonReturnStringAsBlob(pStr);
drh4500d872023-10-03 22:40:224884 if( isFinal ){
drh2a27be22023-12-08 14:54:224885 if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf);
drh4500d872023-10-03 22:40:224886 }else{
drh777a0882024-01-20 12:13:004887 jsonStringTrimOneChar(pStr);
drh4500d872023-10-03 22:40:224888 }
drh7e86d3f2023-09-30 14:34:394889 return;
drh8be47a72018-07-05 20:05:294890 }else if( isFinal ){
mistachkined008ec2018-09-12 01:05:264891 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
drhf02cc9a2023-07-25 15:08:184892 pStr->bStatic ? SQLITE_TRANSIENT :
drh43dc31c2023-10-17 19:33:524893 sqlite3RCStrUnref);
drhff135ae2015-12-30 01:07:024894 pStr->bStatic = 1;
drh8be47a72018-07-05 20:05:294895 }else{
mistachkined008ec2018-09-12 01:05:264896 sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT);
drh777a0882024-01-20 12:13:004897 jsonStringTrimOneChar(pStr);
drhff135ae2015-12-30 01:07:024898 }
4899 }else{
4900 sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC);
4901 }
4902 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
4903}
drh8be47a72018-07-05 20:05:294904static void jsonObjectValue(sqlite3_context *ctx){
4905 jsonObjectCompute(ctx, 0);
4906}
4907static void jsonObjectFinal(sqlite3_context *ctx){
4908 jsonObjectCompute(ctx, 1);
4909}
4910
drhff135ae2015-12-30 01:07:024911
4912
drhd2975922015-08-29 17:22:334913#ifndef SQLITE_OMIT_VIRTUALTABLE
drhcb6c6c62015-08-19 22:47:174914/****************************************************************************
4915** The json_each virtual table
4916****************************************************************************/
drhabbdbdf2023-11-24 18:44:004917typedef struct JsonParent JsonParent;
4918struct JsonParent {
4919 u32 iHead; /* Start of object or array */
drh5e6500c2023-11-24 21:57:384920 u32 iValue; /* Start of the value */
drhabbdbdf2023-11-24 18:44:004921 u32 iEnd; /* First byte past the end */
drhc2474102023-11-25 18:11:114922 u32 nPath; /* Length of path */
drhabbdbdf2023-11-24 18:44:004923 i64 iKey; /* Key for JSONB_ARRAY */
4924};
4925
drhcb6c6c62015-08-19 22:47:174926typedef struct JsonEachCursor JsonEachCursor;
4927struct JsonEachCursor {
4928 sqlite3_vtab_cursor base; /* Base class - must be first */
drh505ad2c2015-08-21 17:33:114929 u32 iRowid; /* The rowid */
drhabbdbdf2023-11-24 18:44:004930 u32 i; /* Index in sParse.aBlob[] of current row */
drh505ad2c2015-08-21 17:33:114931 u32 iEnd; /* EOF when i equals or exceeds this value */
drh50b37832023-11-26 00:48:374932 u32 nRoot; /* Size of the root path in bytes */
drhabbdbdf2023-11-24 18:44:004933 u8 eType; /* Type of the container for element i */
drh505ad2c2015-08-21 17:33:114934 u8 bRecursive; /* True for json_tree(). False for json_each() */
drhabbdbdf2023-11-24 18:44:004935 u32 nParent; /* Current nesting depth */
4936 u32 nParentAlloc; /* Space allocated for aParent[] */
4937 JsonParent *aParent; /* Parent elements of i */
drhabbdbdf2023-11-24 18:44:004938 sqlite3 *db; /* Database connection */
drhc2474102023-11-25 18:11:114939 JsonString path; /* Current path */
drh505ad2c2015-08-21 17:33:114940 JsonParse sParse; /* Parse of the input JSON */
drhcb6c6c62015-08-19 22:47:174941};
drhabbdbdf2023-11-24 18:44:004942typedef struct JsonEachConnection JsonEachConnection;
4943struct JsonEachConnection {
4944 sqlite3_vtab base; /* Base class - must be first */
4945 sqlite3 *db; /* Database connection */
4946};
4947
drhcb6c6c62015-08-19 22:47:174948
4949/* Constructor for the json_each virtual table */
4950static int jsonEachConnect(
4951 sqlite3 *db,
4952 void *pAux,
4953 int argc, const char *const*argv,
4954 sqlite3_vtab **ppVtab,
4955 char **pzErr
4956){
drhabbdbdf2023-11-24 18:44:004957 JsonEachConnection *pNew;
drh505ad2c2015-08-21 17:33:114958 int rc;
drhcb6c6c62015-08-19 22:47:174959
4960/* Column numbers */
drh4af352d2015-08-21 20:02:484961#define JEACH_KEY 0
4962#define JEACH_VALUE 1
4963#define JEACH_TYPE 2
4964#define JEACH_ATOM 3
4965#define JEACH_ID 4
4966#define JEACH_PARENT 5
4967#define JEACH_FULLKEY 6
drh383de692015-09-10 17:20:574968#define JEACH_PATH 7
drh43579192018-11-16 16:04:504969/* The xBestIndex method assumes that the JSON and ROOT columns are
4970** the last two columns in the table. Should this ever changes, be
4971** sure to update the xBestIndex method. */
drh383de692015-09-10 17:20:574972#define JEACH_JSON 8
4973#define JEACH_ROOT 9
drhcb6c6c62015-08-19 22:47:174974
drh9dbf96b2022-01-06 01:40:094975 UNUSED_PARAMETER(pzErr);
4976 UNUSED_PARAMETER(argv);
4977 UNUSED_PARAMETER(argc);
4978 UNUSED_PARAMETER(pAux);
drh77253702023-07-26 11:43:394979 rc = sqlite3_declare_vtab(db,
drh383de692015-09-10 17:20:574980 "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path,"
4981 "json HIDDEN,root HIDDEN)");
drh505ad2c2015-08-21 17:33:114982 if( rc==SQLITE_OK ){
drh4093b292024-01-03 16:41:504983 pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
4984 *ppVtab = (sqlite3_vtab*)pNew;
drh505ad2c2015-08-21 17:33:114985 if( pNew==0 ) return SQLITE_NOMEM;
drh2b1c2aa2020-01-07 19:45:404986 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
drhabbdbdf2023-11-24 18:44:004987 pNew->db = db;
drh505ad2c2015-08-21 17:33:114988 }
4989 return rc;
drhcb6c6c62015-08-19 22:47:174990}
4991
4992/* destructor for json_each virtual table */
4993static int jsonEachDisconnect(sqlite3_vtab *pVtab){
drh4093b292024-01-03 16:41:504994 JsonEachConnection *p = (JsonEachConnection*)pVtab;
4995 sqlite3DbFree(p->db, pVtab);
drhcb6c6c62015-08-19 22:47:174996 return SQLITE_OK;
4997}
4998
drh505ad2c2015-08-21 17:33:114999/* constructor for a JsonEachCursor object for json_each(). */
5000static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
drhabbdbdf2023-11-24 18:44:005001 JsonEachConnection *pVtab = (JsonEachConnection*)p;
drhcb6c6c62015-08-19 22:47:175002 JsonEachCursor *pCur;
drh6fd5c1e2015-08-21 20:37:125003
drh9dbf96b2022-01-06 01:40:095004 UNUSED_PARAMETER(p);
drh4093b292024-01-03 16:41:505005 pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur));
drhcb6c6c62015-08-19 22:47:175006 if( pCur==0 ) return SQLITE_NOMEM;
drhabbdbdf2023-11-24 18:44:005007 pCur->db = pVtab->db;
drhc2474102023-11-25 18:11:115008 jsonStringZero(&pCur->path);
drhcb6c6c62015-08-19 22:47:175009 *ppCursor = &pCur->base;
5010 return SQLITE_OK;
5011}
5012
drh505ad2c2015-08-21 17:33:115013/* constructor for a JsonEachCursor object for json_tree(). */
5014static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
5015 int rc = jsonEachOpenEach(p, ppCursor);
5016 if( rc==SQLITE_OK ){
5017 JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
5018 pCur->bRecursive = 1;
5019 }
5020 return rc;
5021}
5022
drhcb6c6c62015-08-19 22:47:175023/* Reset a JsonEachCursor back to its original state. Free any memory
5024** held. */
5025static void jsonEachCursorReset(JsonEachCursor *p){
drh505ad2c2015-08-21 17:33:115026 jsonParseReset(&p->sParse);
drhc2474102023-11-25 18:11:115027 jsonStringReset(&p->path);
drhabbdbdf2023-11-24 18:44:005028 sqlite3DbFree(p->db, p->aParent);
drhcb6c6c62015-08-19 22:47:175029 p->iRowid = 0;
5030 p->i = 0;
drhabbdbdf2023-11-24 18:44:005031 p->aParent = 0;
5032 p->nParent = 0;
5033 p->nParentAlloc = 0;
drhcb6c6c62015-08-19 22:47:175034 p->iEnd = 0;
5035 p->eType = 0;
drhcb6c6c62015-08-19 22:47:175036}
5037
5038/* Destructor for a jsonEachCursor object */
5039static int jsonEachClose(sqlite3_vtab_cursor *cur){
5040 JsonEachCursor *p = (JsonEachCursor*)cur;
5041 jsonEachCursorReset(p);
drhc2474102023-11-25 18:11:115042
drh4093b292024-01-03 16:41:505043 sqlite3DbFree(p->db, cur);
drhcb6c6c62015-08-19 22:47:175044 return SQLITE_OK;
5045}
5046
5047/* Return TRUE if the jsonEachCursor object has been advanced off the end
5048** of the JSON object */
5049static int jsonEachEof(sqlite3_vtab_cursor *cur){
5050 JsonEachCursor *p = (JsonEachCursor*)cur;
5051 return p->i >= p->iEnd;
5052}
5053
drhabbdbdf2023-11-24 18:44:005054/*
5055** If the cursor is currently pointing at the label of a object entry,
5056** then return the index of the value. For all other cases, return the
5057** current pointer position, which is the value.
5058*/
5059static int jsonSkipLabel(JsonEachCursor *p){
5060 if( p->eType==JSONB_OBJECT ){
5061 u32 sz = 0;
5062 u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
5063 return p->i + n + sz;
5064 }else{
5065 return p->i;
5066 }
5067}
5068
drhc2474102023-11-25 18:11:115069/*
5070** Append the path name for the current element.
5071*/
5072static void jsonAppendPathName(JsonEachCursor *p){
5073 assert( p->nParent>0 );
5074 assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT );
5075 if( p->eType==JSONB_ARRAY ){
5076 jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey);
5077 }else{
5078 u32 n, sz = 0, k, i;
5079 const char *z;
5080 int needQuote = 0;
5081 n = jsonbPayloadSize(&p->sParse, p->i, &sz);
5082 k = p->i + n;
5083 z = (const char*)&p->sParse.aBlob[k];
5084 if( sz==0 || !sqlite3Isalpha(z[0]) ){
5085 needQuote = 1;
5086 }else{
5087 for(i=0; i<sz; i++){
5088 if( !sqlite3Isalnum(z[i]) ){
5089 needQuote = 1;
5090 break;
5091 }
5092 }
5093 }
5094 if( needQuote ){
5095 jsonPrintf(sz+4,&p->path,".\"%.*s\"", sz, z);
5096 }else{
5097 jsonPrintf(sz+2,&p->path,".%.*s", sz, z);
5098 }
5099 }
5100}
5101
drh505ad2c2015-08-21 17:33:115102/* Advance the cursor to the next element for json_tree() */
drh4af352d2015-08-21 20:02:485103static int jsonEachNext(sqlite3_vtab_cursor *cur){
drh505ad2c2015-08-21 17:33:115104 JsonEachCursor *p = (JsonEachCursor*)cur;
drhb4e5bc62023-11-27 12:30:555105 int rc = SQLITE_OK;
drh796abda2023-11-25 20:59:035106 if( p->bRecursive ){
drhabbdbdf2023-11-24 18:44:005107 u8 x;
5108 u8 levelChange = 0;
5109 u32 n, sz = 0;
5110 u32 i = jsonSkipLabel(p);
5111 x = p->sParse.aBlob[i] & 0x0f;
drh5e6500c2023-11-24 21:57:385112 n = jsonbPayloadSize(&p->sParse, i, &sz);
drhabbdbdf2023-11-24 18:44:005113 if( x==JSONB_OBJECT || x==JSONB_ARRAY ){
5114 JsonParent *pParent;
5115 if( p->nParent>=p->nParentAlloc ){
5116 JsonParent *pNew;
5117 u64 nNew;
5118 nNew = p->nParentAlloc*2 + 3;
5119 pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew);
5120 if( pNew==0 ) return SQLITE_NOMEM;
5121 p->nParentAlloc = (u32)nNew;
5122 p->aParent = pNew;
drh4af352d2015-08-21 20:02:485123 }
drh5e6500c2023-11-24 21:57:385124 levelChange = 1;
drhc2474102023-11-25 18:11:115125 pParent = &p->aParent[p->nParent];
drhabbdbdf2023-11-24 18:44:005126 pParent->iHead = p->i;
drh5e6500c2023-11-24 21:57:385127 pParent->iValue = i;
5128 pParent->iEnd = i + n + sz;
5129 pParent->iKey = -1;
drhc2474102023-11-25 18:11:115130 pParent->nPath = (u32)p->path.nUsed;
drhb4e5bc62023-11-27 12:30:555131 if( p->eType && p->nParent ){
5132 jsonAppendPathName(p);
5133 if( p->path.eErr ) rc = SQLITE_NOMEM;
5134 }
drhc2474102023-11-25 18:11:115135 p->nParent++;
drh5e6500c2023-11-24 21:57:385136 p->i = i + n;
drhabbdbdf2023-11-24 18:44:005137 }else{
5138 p->i = i + n + sz;
5139 }
drh5e6500c2023-11-24 21:57:385140 while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){
drhabbdbdf2023-11-24 18:44:005141 p->nParent--;
drhc2474102023-11-25 18:11:115142 p->path.nUsed = p->aParent[p->nParent].nPath;
drhabbdbdf2023-11-24 18:44:005143 levelChange = 1;
5144 }
5145 if( levelChange ){
5146 if( p->nParent>0 ){
drh5e6500c2023-11-24 21:57:385147 JsonParent *pParent = &p->aParent[p->nParent-1];
drh53c21602023-12-02 18:17:385148 u32 iVal = pParent->iValue;
5149 p->eType = p->sParse.aBlob[iVal] & 0x0f;
drhabbdbdf2023-11-24 18:44:005150 }else{
5151 p->eType = 0;
drh4af352d2015-08-21 20:02:485152 }
drh505ad2c2015-08-21 17:33:115153 }
drhabbdbdf2023-11-24 18:44:005154 }else{
5155 u32 n, sz = 0;
5156 u32 i = jsonSkipLabel(p);
5157 n = jsonbPayloadSize(&p->sParse, i, &sz);
5158 p->i = i + n + sz;
drh505ad2c2015-08-21 17:33:115159 }
drh15c0b032023-11-26 00:56:405160 if( p->eType==JSONB_ARRAY && p->nParent ){
drh50b37832023-11-26 00:48:375161 p->aParent[p->nParent-1].iKey++;
5162 }
drh5e6500c2023-11-24 21:57:385163 p->iRowid++;
drhb4e5bc62023-11-27 12:30:555164 return rc;
drh505ad2c2015-08-21 17:33:115165}
5166
drh50b37832023-11-26 00:48:375167/* Length of the path for rowid==0 in bRecursive mode.
5168*/
5169static int jsonEachPathLength(JsonEachCursor *p){
5170 u32 n = p->path.nUsed;
drh5a238ff2023-12-07 14:09:255171 char *z = p->path.zBuf;
5172 if( p->iRowid==0 && p->bRecursive && n>=2 ){
5173 while( n>1 ){
5174 n--;
5175 if( z[n]=='[' || z[n]=='.' ){
5176 u32 x, sz = 0;
5177 char cSaved = z[n];
5178 z[n] = 0;
5179 assert( p->sParse.eEdit==0 );
5180 x = jsonLookupStep(&p->sParse, 0, z+1, 0);
5181 z[n] = cSaved;
5182 if( JSON_LOOKUP_ISERROR(x) ) continue;
5183 if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break;
5184 }
drh50b37832023-11-26 00:48:375185 }
5186 }
5187 return n;
5188}
5189
drhcb6c6c62015-08-19 22:47:175190/* Return the value of a column */
5191static int jsonEachColumn(
5192 sqlite3_vtab_cursor *cur, /* The cursor */
5193 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
drhabbdbdf2023-11-24 18:44:005194 int iColumn /* Which column to return */
drhcb6c6c62015-08-19 22:47:175195){
5196 JsonEachCursor *p = (JsonEachCursor*)cur;
drh796abda2023-11-25 20:59:035197 switch( iColumn ){
5198 case JEACH_KEY: {
drh50b37832023-11-26 00:48:375199 if( p->nParent==0 ){
5200 u32 n, j;
drh50b37832023-11-26 00:48:375201 if( p->nRoot==1 ) break;
5202 j = jsonEachPathLength(p);
5203 n = p->nRoot - j;
drhb4e5bc62023-11-27 12:30:555204 if( n==0 ){
5205 break;
5206 }else if( p->path.zBuf[j]=='[' ){
drh50b37832023-11-26 00:48:375207 i64 x;
5208 sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8);
5209 sqlite3_result_int64(ctx, x);
5210 }else if( p->path.zBuf[j+1]=='"' ){
5211 sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT);
5212 }else{
5213 sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT);
5214 }
5215 break;
5216 }
drh796abda2023-11-25 20:59:035217 if( p->eType==JSONB_OBJECT ){
5218 jsonReturnFromBlob(&p->sParse, p->i, ctx, 1);
5219 }else{
5220 assert( p->eType==JSONB_ARRAY );
5221 sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey);
drhabbdbdf2023-11-24 18:44:005222 }
drh796abda2023-11-25 20:59:035223 break;
drhcb6c6c62015-08-19 22:47:175224 }
drh796abda2023-11-25 20:59:035225 case JEACH_VALUE: {
5226 u32 i = jsonSkipLabel(p);
5227 jsonReturnFromBlob(&p->sParse, i, ctx, 1);
drh4dd59fd92024-02-16 21:30:085228 if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
5229 sqlite3_result_subtype(ctx, JSON_SUBTYPE);
5230 }
drh796abda2023-11-25 20:59:035231 break;
5232 }
5233 case JEACH_TYPE: {
5234 u32 i = jsonSkipLabel(p);
drh5afd67b2023-12-05 19:24:075235 u8 eType = p->sParse.aBlob[i] & 0x0f;
drh796abda2023-11-25 20:59:035236 sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC);
5237 break;
5238 }
5239 case JEACH_ATOM: {
5240 u32 i = jsonSkipLabel(p);
5241 if( (p->sParse.aBlob[i] & 0x0f)<JSONB_ARRAY ){
drhabbdbdf2023-11-24 18:44:005242 jsonReturnFromBlob(&p->sParse, i, ctx, 1);
drhabbdbdf2023-11-24 18:44:005243 }
drh796abda2023-11-25 20:59:035244 break;
drhabbdbdf2023-11-24 18:44:005245 }
drh796abda2023-11-25 20:59:035246 case JEACH_ID: {
5247 sqlite3_result_int64(ctx, (sqlite3_int64)p->i);
5248 break;
5249 }
5250 case JEACH_PARENT: {
drh50b37832023-11-26 00:48:375251 if( p->nParent>0 && p->bRecursive ){
drh796abda2023-11-25 20:59:035252 sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead);
5253 }
5254 break;
5255 }
5256 case JEACH_FULLKEY: {
5257 u64 nBase = p->path.nUsed;
5258 if( p->nParent ) jsonAppendPathName(p);
5259 sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed,
5260 SQLITE_TRANSIENT, SQLITE_UTF8);
5261 p->path.nUsed = nBase;
5262 break;
5263 }
5264 case JEACH_PATH: {
drh50b37832023-11-26 00:48:375265 u32 n = jsonEachPathLength(p);
5266 sqlite3_result_text64(ctx, p->path.zBuf, n,
drh796abda2023-11-25 20:59:035267 SQLITE_TRANSIENT, SQLITE_UTF8);
5268 break;
5269 }
5270 default: {
drhe09a38c2023-11-25 23:00:505271 sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC);
drh796abda2023-11-25 20:59:035272 break;
5273 }
5274 case JEACH_JSON: {
drh4b9ed1b2023-11-30 23:36:145275 if( p->sParse.zJson==0 ){
drh796abda2023-11-25 20:59:035276 sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob,
drh28001202024-03-05 16:47:485277 SQLITE_TRANSIENT);
drh796abda2023-11-25 20:59:035278 }else{
drh28001202024-03-05 16:47:485279 sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_TRANSIENT);
drh796abda2023-11-25 20:59:035280 }
5281 break;
5282 }
drhcb6c6c62015-08-19 22:47:175283 }
5284 return SQLITE_OK;
5285}
5286
5287/* Return the current rowid value */
5288static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
5289 JsonEachCursor *p = (JsonEachCursor*)cur;
5290 *pRowid = p->iRowid;
5291 return SQLITE_OK;
5292}
5293
5294/* The query strategy is to look for an equality constraint on the json
5295** column. Without such a constraint, the table cannot operate. idxNum is
drh383de692015-09-10 17:20:575296** 1 if the constraint is found, 3 if the constraint and zRoot are found,
drhcb6c6c62015-08-19 22:47:175297** and 0 otherwise.
5298*/
5299static int jsonEachBestIndex(
5300 sqlite3_vtab *tab,
5301 sqlite3_index_info *pIdxInfo
5302){
drh43579192018-11-16 16:04:505303 int i; /* Loop counter or computed array index */
5304 int aIdx[2]; /* Index of constraints for JSON and ROOT */
5305 int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */
5306 int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */
drhcb6c6c62015-08-19 22:47:175307 const struct sqlite3_index_constraint *pConstraint;
drh6fd5c1e2015-08-21 20:37:125308
drh43579192018-11-16 16:04:505309 /* This implementation assumes that JSON and ROOT are the last two
5310 ** columns in the table */
5311 assert( JEACH_ROOT == JEACH_JSON+1 );
drh9dbf96b2022-01-06 01:40:095312 UNUSED_PARAMETER(tab);
drh43579192018-11-16 16:04:505313 aIdx[0] = aIdx[1] = -1;
drhcb6c6c62015-08-19 22:47:175314 pConstraint = pIdxInfo->aConstraint;
5315 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
drh43579192018-11-16 16:04:505316 int iCol;
5317 int iMask;
5318 if( pConstraint->iColumn < JEACH_JSON ) continue;
5319 iCol = pConstraint->iColumn - JEACH_JSON;
5320 assert( iCol==0 || iCol==1 );
drh285f2ef2021-10-15 16:15:045321 testcase( iCol==0 );
drh43579192018-11-16 16:04:505322 iMask = 1 << iCol;
5323 if( pConstraint->usable==0 ){
5324 unusableMask |= iMask;
5325 }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
5326 aIdx[iCol] = i;
5327 idxMask |= iMask;
drhcb6c6c62015-08-19 22:47:175328 }
5329 }
drh77253702023-07-26 11:43:395330 if( pIdxInfo->nOrderBy>0
5331 && pIdxInfo->aOrderBy[0].iColumn<0
dan19ab86f2023-01-17 15:46:275332 && pIdxInfo->aOrderBy[0].desc==0
5333 ){
5334 pIdxInfo->orderByConsumed = 1;
5335 }
5336
drh43579192018-11-16 16:04:505337 if( (unusableMask & ~idxMask)!=0 ){
5338 /* If there are any unusable constraints on JSON or ROOT, then reject
5339 ** this entire plan */
5340 return SQLITE_CONSTRAINT;
5341 }
5342 if( aIdx[0]<0 ){
5343 /* No JSON input. Leave estimatedCost at the huge value that it was
5344 ** initialized to to discourage the query planner from selecting this
5345 ** plan. */
drhcb6c6c62015-08-19 22:47:175346 pIdxInfo->idxNum = 0;
drhcb6c6c62015-08-19 22:47:175347 }else{
drh505ad2c2015-08-21 17:33:115348 pIdxInfo->estimatedCost = 1.0;
drh43579192018-11-16 16:04:505349 i = aIdx[0];
5350 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
5351 pIdxInfo->aConstraintUsage[i].omit = 1;
5352 if( aIdx[1]<0 ){
5353 pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
drhcb6c6c62015-08-19 22:47:175354 }else{
drh43579192018-11-16 16:04:505355 i = aIdx[1];
5356 pIdxInfo->aConstraintUsage[i].argvIndex = 2;
5357 pIdxInfo->aConstraintUsage[i].omit = 1;
5358 pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
drhcb6c6c62015-08-19 22:47:175359 }
5360 }
5361 return SQLITE_OK;
5362}
5363
5364/* Start a search on a new JSON string */
5365static int jsonEachFilter(
5366 sqlite3_vtab_cursor *cur,
5367 int idxNum, const char *idxStr,
5368 int argc, sqlite3_value **argv
5369){
5370 JsonEachCursor *p = (JsonEachCursor*)cur;
mistachkin16a93122015-09-11 18:05:015371 const char *zRoot = 0;
drh796abda2023-11-25 20:59:035372 u32 i, n, sz;
drhcb6c6c62015-08-19 22:47:175373
drh9dbf96b2022-01-06 01:40:095374 UNUSED_PARAMETER(idxStr);
5375 UNUSED_PARAMETER(argc);
drhcb6c6c62015-08-19 22:47:175376 jsonEachCursorReset(p);
5377 if( idxNum==0 ) return SQLITE_OK;
drhabbdbdf2023-11-24 18:44:005378 memset(&p->sParse, 0, sizeof(p->sParse));
5379 p->sParse.nJPRef = 1;
drh4093b292024-01-03 16:41:505380 p->sParse.db = p->db;
drhcbe4a262025-04-21 19:53:125381 if( jsonArgIsJsonb(argv[0], &p->sParse) ){
5382 /* We have JSONB */
drh796abda2023-11-25 20:59:035383 }else{
5384 p->sParse.zJson = (char*)sqlite3_value_text(argv[0]);
5385 p->sParse.nJson = sqlite3_value_bytes(argv[0]);
drhb4e5bc62023-11-27 12:30:555386 if( p->sParse.zJson==0 ){
5387 p->i = p->iEnd = 0;
5388 return SQLITE_OK;
5389 }
5390 if( jsonConvertTextToBlob(&p->sParse, 0) ){
drh796abda2023-11-25 20:59:035391 if( p->sParse.oom ){
5392 return SQLITE_NOMEM;
drhb7d5cb72023-11-25 13:40:195393 }
drh16e8a5b2023-12-03 23:30:595394 goto json_each_malformed_input;
drh796abda2023-11-25 20:59:035395 }
5396 }
5397 if( idxNum==3 ){
5398 zRoot = (const char*)sqlite3_value_text(argv[1]);
5399 if( zRoot==0 ) return SQLITE_OK;
5400 if( zRoot[0]!='$' ){
5401 sqlite3_free(cur->pVtab->zErrMsg);
drheb18ae32023-12-03 00:51:305402 cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot);
drh796abda2023-11-25 20:59:035403 jsonEachCursorReset(p);
5404 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
5405 }
drh16e8a5b2023-12-03 23:30:595406 p->nRoot = sqlite3Strlen30(zRoot);
drh796abda2023-11-25 20:59:035407 if( zRoot[1]==0 ){
drhb7d5cb72023-11-25 13:40:195408 i = p->i = 0;
5409 p->eType = 0;
drh796abda2023-11-25 20:59:035410 }else{
drh53c21602023-12-02 18:17:385411 i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0);
5412 if( JSON_LOOKUP_ISERROR(i) ){
5413 if( i==JSON_LOOKUP_NOTFOUND ){
drhb4e5bc62023-11-27 12:30:555414 p->i = 0;
5415 p->eType = 0;
5416 p->iEnd = 0;
5417 return SQLITE_OK;
5418 }
5419 sqlite3_free(cur->pVtab->zErrMsg);
drheb18ae32023-12-03 00:51:305420 cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot);
drhb4e5bc62023-11-27 12:30:555421 jsonEachCursorReset(p);
5422 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
drhcb6c6c62015-08-19 22:47:175423 }
drh796abda2023-11-25 20:59:035424 if( p->sParse.iLabel ){
5425 p->i = p->sParse.iLabel;
5426 p->eType = JSONB_OBJECT;
drh852944e2015-09-10 03:29:115427 }else{
drh796abda2023-11-25 20:59:035428 p->i = i;
5429 p->eType = JSONB_ARRAY;
drh852944e2015-09-10 03:29:115430 }
drhcb6c6c62015-08-19 22:47:175431 }
drh50b37832023-11-26 00:48:375432 jsonAppendRaw(&p->path, zRoot, p->nRoot);
drh796abda2023-11-25 20:59:035433 }else{
5434 i = p->i = 0;
5435 p->eType = 0;
drh50b37832023-11-26 00:48:375436 p->nRoot = 1;
drh796abda2023-11-25 20:59:035437 jsonAppendRaw(&p->path, "$", 1);
5438 }
5439 p->nParent = 0;
drh796abda2023-11-25 20:59:035440 n = jsonbPayloadSize(&p->sParse, i, &sz);
5441 p->iEnd = i+n+sz;
5442 if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){
5443 p->i = i + n;
5444 p->eType = p->sParse.aBlob[i] & 0x0f;
5445 p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent));
5446 if( p->aParent==0 ) return SQLITE_NOMEM;
5447 p->nParent = 1;
5448 p->nParentAlloc = 1;
5449 p->aParent[0].iKey = 0;
5450 p->aParent[0].iEnd = p->iEnd;
5451 p->aParent[0].iHead = p->i;
5452 p->aParent[0].iValue = i;
drhcb6c6c62015-08-19 22:47:175453 }
drha8f39a92015-09-21 22:53:165454 return SQLITE_OK;
drh16e8a5b2023-12-03 23:30:595455
5456json_each_malformed_input:
5457 sqlite3_free(cur->pVtab->zErrMsg);
5458 cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON");
5459 jsonEachCursorReset(p);
5460 return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
drhcb6c6c62015-08-19 22:47:175461}
5462
5463/* The methods of the json_each virtual table */
5464static sqlite3_module jsonEachModule = {
5465 0, /* iVersion */
5466 0, /* xCreate */
5467 jsonEachConnect, /* xConnect */
5468 jsonEachBestIndex, /* xBestIndex */
5469 jsonEachDisconnect, /* xDisconnect */
5470 0, /* xDestroy */
drh505ad2c2015-08-21 17:33:115471 jsonEachOpenEach, /* xOpen - open a cursor */
drhcb6c6c62015-08-19 22:47:175472 jsonEachClose, /* xClose - close a cursor */
5473 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:485474 jsonEachNext, /* xNext - advance a cursor */
drhcb6c6c62015-08-19 22:47:175475 jsonEachEof, /* xEof - check for end of scan */
5476 jsonEachColumn, /* xColumn - read data */
5477 jsonEachRowid, /* xRowid - read data */
5478 0, /* xUpdate */
5479 0, /* xBegin */
5480 0, /* xSync */
5481 0, /* xCommit */
5482 0, /* xRollback */
5483 0, /* xFindMethod */
5484 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:125485 0, /* xSavepoint */
5486 0, /* xRelease */
drh84c501b2018-11-05 23:01:455487 0, /* xRollbackTo */
drh19358872023-10-06 12:51:055488 0, /* xShadowName */
5489 0 /* xIntegrity */
drhcb6c6c62015-08-19 22:47:175490};
5491
drh505ad2c2015-08-21 17:33:115492/* The methods of the json_tree virtual table. */
5493static sqlite3_module jsonTreeModule = {
5494 0, /* iVersion */
5495 0, /* xCreate */
5496 jsonEachConnect, /* xConnect */
5497 jsonEachBestIndex, /* xBestIndex */
5498 jsonEachDisconnect, /* xDisconnect */
5499 0, /* xDestroy */
5500 jsonEachOpenTree, /* xOpen - open a cursor */
5501 jsonEachClose, /* xClose - close a cursor */
5502 jsonEachFilter, /* xFilter - configure scan constraints */
drh4af352d2015-08-21 20:02:485503 jsonEachNext, /* xNext - advance a cursor */
drh505ad2c2015-08-21 17:33:115504 jsonEachEof, /* xEof - check for end of scan */
5505 jsonEachColumn, /* xColumn - read data */
5506 jsonEachRowid, /* xRowid - read data */
5507 0, /* xUpdate */
5508 0, /* xBegin */
5509 0, /* xSync */
5510 0, /* xCommit */
5511 0, /* xRollback */
5512 0, /* xFindMethod */
5513 0, /* xRename */
drh6fd5c1e2015-08-21 20:37:125514 0, /* xSavepoint */
5515 0, /* xRelease */
drh84c501b2018-11-05 23:01:455516 0, /* xRollbackTo */
drh19358872023-10-06 12:51:055517 0, /* xShadowName */
5518 0 /* xIntegrity */
drh505ad2c2015-08-21 17:33:115519};
drhd2975922015-08-29 17:22:335520#endif /* SQLITE_OMIT_VIRTUALTABLE */
drh9dbf96b2022-01-06 01:40:095521#endif /* !defined(SQLITE_OMIT_JSON) */
drh505ad2c2015-08-21 17:33:115522
drh9dbf96b2022-01-06 01:40:095523/*
5524** Register JSON functions.
5525*/
5526void sqlite3RegisterJsonFunctions(void){
5527#ifndef SQLITE_OMIT_JSON
5528 static FuncDef aJsonFunc[] = {
drhe8d4fd52023-11-10 18:59:235529 /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */
5530 /* | | */
5531 /* Uses cache ------, | | ,---- Returns JSONB */
5532 /* | | | | */
5533 /* Number of arguments ---, | | | | ,--- Flags */
5534 /* | | | | | | */
5535 JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc),
drh16e8a5b2023-12-03 23:30:595536 JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc),
drhe8d4fd52023-11-10 18:59:235537 JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc),
5538 JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc),
5539 JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc),
5540 JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc),
5541 JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc),
5542 JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc),
5543 JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc),
5544 JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc),
5545 JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc),
5546 JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc),
5547 JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc),
5548 JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc),
5549 JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc),
5550 JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc),
5551 JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc),
drhb4e7d592024-03-06 14:30:425552 JFUNCTION(json_pretty, 1,1,0, 0,0,0, jsonPrettyFunc),
5553 JFUNCTION(json_pretty, 2,1,0, 0,0,0, jsonPrettyFunc),
drhe8d4fd52023-11-10 18:59:235554 JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc),
5555 JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc),
5556 JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc),
5557 JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc),
5558 JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc),
5559 JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc),
5560 JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc),
5561 JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc),
5562 JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc),
5563 JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc),
drh821a4c92023-11-27 15:57:115564 JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc),
drh301eecc2015-08-17 20:14:195565#if SQLITE_DEBUG
drhe8d4fd52023-11-10 18:59:235566 JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc),
drh301eecc2015-08-17 20:14:195567#endif
drh77253702023-07-26 11:43:395568 WAGGREGATE(json_group_array, 1, 0, 0,
drh9dbf96b2022-01-06 01:40:095569 jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
drh194b8d52023-11-09 12:08:165570 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
drh243f2ec2023-11-08 21:38:305571 SQLITE_DETERMINISTIC),
drh7e86d3f2023-09-30 14:34:395572 WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0,
5573 jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
drhe8d4fd52023-11-10 18:59:235574 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
drh77253702023-07-26 11:43:395575 WAGGREGATE(json_group_object, 2, 0, 0,
drh9dbf96b2022-01-06 01:40:095576 jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
drhe8d4fd52023-11-10 18:59:235577 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
drh7e86d3f2023-09-30 14:34:395578 WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0,
5579 jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
drh194b8d52023-11-09 12:08:165580 SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
drh243f2ec2023-11-08 21:38:305581 SQLITE_DETERMINISTIC)
drh5fa5c102015-08-12 16:49:405582 };
drh9dbf96b2022-01-06 01:40:095583 sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
5584#endif
5585}
5586
5587#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
5588/*
5589** Register the JSON table-valued functions
5590*/
5591int sqlite3JsonTableFunctions(sqlite3 *db){
5592 int rc = SQLITE_OK;
drh505ad2c2015-08-21 17:33:115593 static const struct {
drhdaefcd92022-01-08 15:37:135594 const char *zName;
5595 sqlite3_module *pModule;
drh505ad2c2015-08-21 17:33:115596 } aMod[] = {
5597 { "json_each", &jsonEachModule },
5598 { "json_tree", &jsonTreeModule },
5599 };
drh69b0ce32022-02-04 13:15:015600 unsigned int i;
drh505ad2c2015-08-21 17:33:115601 for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
5602 rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
drhcb6c6c62015-08-19 22:47:175603 }
drh5fa5c102015-08-12 16:49:405604 return rc;
5605}
drh9dbf96b2022-01-06 01:40:095606#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */