aboutsummaryrefslogtreecommitdiff
path: root/ext/misc/json1.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2019-11-22 17:37:56 +0000
committerdrh <drh@noemail.net>2019-11-22 17:37:56 +0000
commit5281864f0ca2637ed0d92913709a244046c239a2 (patch)
treeb8c538a2f88ef1fc7172ca24dfb5655a09d14dd1 /ext/misc/json1.c
parent22de8357dfbc077ecedb1ebe7439a409f7903c6b (diff)
downloadsqlite-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.c41
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(;;){