aboutsummaryrefslogtreecommitdiff
path: root/src/json.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/json.c')
-rw-r--r--src/json.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/src/json.c b/src/json.c
index 5823eadc8..503fff936 100644
--- a/src/json.c
+++ b/src/json.c
@@ -353,6 +353,7 @@ struct JsonParse {
u8 eEdit; /* Edit operation to apply */
int delta; /* Size change due to the edit */
u32 nIns; /* Number of bytes to insert */
+ u32 iLabel; /* Location of label if search landed on an object value */
u8 *aIns; /* Content to be inserted */
};
@@ -3904,6 +3905,7 @@ static u32 jsonLookupBlobStep(
memcpy(&pParse->aBlob[iRoot], pParse->aIns, pParse->nIns);
}
}
+ pParse->iLabel = iLabel;
return iRoot;
}
if( zPath[0]=='.' ){
@@ -6015,10 +6017,10 @@ static int jsonEachColumn(
break;
}
case JEACH_ATOM: {
- u32 i;
- if( p->eType>=JSON_ARRAY ) break;
- i = jsonSkipLabel(p);
- jsonReturnFromBlob(&p->sParse, i, ctx, 1);
+ u32 i = jsonSkipLabel(p);
+ if( (p->sParse.aBlob[i] & 0x0f)<JSONB_ARRAY ){
+ jsonReturnFromBlob(&p->sParse, i, ctx, 1);
+ }
break;
}
case JEACH_ID: {
@@ -6204,13 +6206,50 @@ static int jsonEachFilter(
if( p->sParse.aBlob==0 ){
return SQLITE_NOMEM;
}
- i = p->i = 0;
- p->iEnd = 0;
- p->eType = 0;
+ if( idxNum==3 ){
+ zRoot = (const char*)sqlite3_value_text(argv[1]);
+ if( zRoot==0 ) return SQLITE_OK;
+ n = sqlite3_value_bytes(argv[1]);
+ p->zRoot = sqlite3_malloc64( n+1 );
+ if( p->zRoot==0 ) return SQLITE_NOMEM;
+ memcpy(p->zRoot, zRoot, (size_t)n+1);
+ if( zRoot[0]!='$' ){
+ sqlite3_free(cur->pVtab->zErrMsg);
+ cur->pVtab->zErrMsg = jsonPathSyntaxError(zRoot, 0);
+ jsonEachCursorReset(p);
+ return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+ }
+ if( zRoot[1]==0 ){
+ i = p->i = 0;
+ p->eType = 0;
+ }else{
+ i = jsonLookupBlobStep(&p->sParse, 0, p->zRoot+1, 0);
+ if( JSON_BLOB_ISERROR(i) ){
+ p->i = 0;
+ p->eType = 0;
+ p->iEnd = 0;
+ return SQLITE_OK;
+ }
+ if( p->sParse.iLabel ){
+ p->i = p->sParse.iLabel;
+ p->eType = JSONB_OBJECT;
+ }else{
+ p->i = i;
+ p->eType = JSONB_ARRAY;
+ }
+ }
+ }else{
+ i = p->i = 0;
+ p->eType = 0;
+ }
p->nParent = 0;
p->sParse.isBinary = 1;
n = jsonbPayloadSize(&p->sParse, i, &sz);
p->iEnd = i+n+sz;
+ if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){
+ p->i += n;
+ p->eType = p->sParse.aBlob[i] & 0x0f;
+ }
return SQLITE_OK;
}else{
z = (const char*)sqlite3_value_text(argv[0]);