diff options
author | drh <drh@noemail.net> | 2019-11-22 17:37:56 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2019-11-22 17:37:56 +0000 |
commit | 5281864f0ca2637ed0d92913709a244046c239a2 (patch) | |
tree | b8c538a2f88ef1fc7172ca24dfb5655a09d14dd1 /ext/misc/json1.c | |
parent | 22de8357dfbc077ecedb1ebe7439a409f7903c6b (diff) | |
download | sqlite-5281864f0ca2637ed0d92913709a244046c239a2.tar.gz sqlite-5281864f0ca2637ed0d92913709a244046c239a2.zip |
Extend the json-path mechanism with array indexes of the form "#" or "#-n" for
some positive number "n", to reference the end of an array.
FossilOrigin-Name: 35ed68a651f4cf8740597433b0f1c3b345841868022e0904e9f342840ba0e502
Diffstat (limited to 'ext/misc/json1.c')
-rw-r--r-- | ext/misc/json1.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 82bffe874..012ac4a89 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1176,18 +1176,49 @@ static JsonNode *jsonLookupStep( } return pNode; } - }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ - if( pRoot->eType!=JSON_ARRAY ) return 0; + }else if( zPath[0]=='[' ){ i = 0; j = 1; while( safe_isdigit(zPath[j]) ){ i = i*10 + zPath[j] - '0'; j++; } - if( zPath[j]!=']' ){ - *pzErr = zPath; - return 0; + if( j<2 || zPath[j]!=']' ){ + if( zPath[1]=='#' ){ + JsonNode *pBase = pRoot; + int iBase = iRoot; + if( pRoot->eType!=JSON_ARRAY ) return 0; + for(;;){ + while( j<=pBase->n ){ + if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++; + j += jsonNodeSize(&pBase[j]); + } + if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; + iBase += pBase->u.iAppend; + pBase = &pParse->aNode[iBase]; + j = 1; + } + j = 2; + if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){ + unsigned int x = 0; + j = 3; + do{ + x = x*10 + zPath[j] - '0'; + j++; + }while( safe_isdigit(zPath[j]) ); + if( x>i ) return 0; + i -= x; + } + if( zPath[j]!=']' ){ + *pzErr = zPath; + return 0; + } + }else{ + *pzErr = zPath; + return 0; + } } + if( pRoot->eType!=JSON_ARRAY ) return 0; zPath += j + 1; j = 1; for(;;){ |