aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/json.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/json.c b/src/json.c
index 37a0ebfe1..44abe2d16 100644
--- a/src/json.c
+++ b/src/json.c
@@ -3272,6 +3272,20 @@ static void jsonArrayLengthFunc(
jsonParseFree(p);
}
+/* True if the string is all digits */
+static int jsonAllDigits(const char *z, int n){
+ int i;
+ for(i=0; i<n && sqlite3Isdigit(z[i]); i++){}
+ return i==n;
+}
+
+/* True if the string is all alphanumerics and underscores */
+static int jsonAllAlphanum(const char *z, int n){
+ int i;
+ for(i=0; i<n && (sqlite3Isalnum(z[i]) || z[i]=='_'); i++){}
+ return i==n;
+}
+
/*
** json_extract(JSON, PATH, ...)
** "->"(JSON,PATH)
@@ -3329,15 +3343,19 @@ static void jsonExtractFunc(
** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
*/
jsonStringInit(&jx, ctx);
- if( sqlite3Isdigit(zPath[0]) ){
+ if( jsonAllDigits(zPath, nPath) ){
jsonAppendRawNZ(&jx, "[", 1);
jsonAppendRaw(&jx, zPath, nPath);
jsonAppendRawNZ(&jx, "]", 2);
- }else if( zPath[0]!='[' ){
+ }else if( jsonAllAlphanum(zPath, nPath) ){
jsonAppendRawNZ(&jx, ".", 1);
jsonAppendRaw(&jx, zPath, nPath);
+ }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){
+ jsonAppendRaw(&jx, zPath, nPath);
}else{
+ jsonAppendRawNZ(&jx, ".\"", 2);
jsonAppendRaw(&jx, zPath, nPath);
+ jsonAppendRawNZ(&jx, "\"", 1);
}
jsonStringTerminate(&jx);
j = jsonLookupStep(p, 0, jx.zBuf, 0);