aboutsummaryrefslogtreecommitdiff
path: root/ext/misc/json1.c
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2015-09-21 22:53:16 +0000
committerdrh <drh@noemail.net>2015-09-21 22:53:16 +0000
commita8f39a9b5d0f824b9eb5f29055a0bf6d5ca25cba (patch)
treecafd1347a1bc5193eb2cfa5a250a4a8dc3bf9d84 /ext/misc/json1.c
parent78ac109c7f7946dd0ac1e67a11cb577210cb2d34 (diff)
downloadsqlite-a8f39a9b5d0f824b9eb5f29055a0bf6d5ca25cba.tar.gz
sqlite-a8f39a9b5d0f824b9eb5f29055a0bf6d5ca25cba.zip
Simplifications to the json1.c logic.
FossilOrigin-Name: 1646a2bd85f87d03a14fcaec288107f5f6411c6f
Diffstat (limited to 'ext/misc/json1.c')
-rw-r--r--ext/misc/json1.c203
1 files changed, 103 insertions, 100 deletions
diff --git a/ext/misc/json1.c b/ext/misc/json1.c
index e115470f8..4e21b151a 100644
--- a/ext/misc/json1.c
+++ b/ext/misc/json1.c
@@ -343,7 +343,8 @@ static void jsonRenderNode(
sqlite3_value **aReplace /* Replacement values */
){
switch( pNode->eType ){
- case JSON_NULL: {
+ default: {
+ assert( pNode->eType==JSON_NULL );
jsonAppendRaw(pOut, "null", 4);
break;
}
@@ -441,7 +442,8 @@ static void jsonReturn(
sqlite3_value **aReplace /* Array of replacement values */
){
switch( pNode->eType ){
- case JSON_NULL: {
+ default: {
+ assert( pNode->eType==JSON_NULL );
sqlite3_result_null(pCtx);
break;
}
@@ -468,10 +470,16 @@ static void jsonReturn(
break;
}
case JSON_STRING: {
+#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
+ ** json_insert() and json_replace() and those routines do not
+ ** call jsonReturn() */
if( pNode->jnFlags & JNODE_RAW ){
sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
SQLITE_TRANSIENT);
- }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
+ }else
+#endif
+ assert( (pNode->jnFlags & JNODE_RAW)==0 );
+ if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
/* JSON formatted without any backslash-escapes */
sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
SQLITE_TRANSIENT);
@@ -604,7 +612,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
while( safe_isspace(pParse->zJson[j]) ){ j++; }
x = jsonParseValue(pParse, j);
if( x<0 ){
- if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
+ if( x==(-2) ) return j+1;
return -1;
}
if( pParse->oom ) return -1;
@@ -634,7 +642,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
while( safe_isspace(pParse->zJson[j]) ){ j++; }
x = jsonParseValue(pParse, j);
if( x<0 ){
- if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
+ if( x==(-3) ) return j+1;
return -1;
}
j = x;
@@ -829,7 +837,12 @@ static JsonNode *jsonLookupStep(
zKey = zPath + 1;
for(i=1; zPath[i] && zPath[i]!='"'; i++){}
nKey = i-1;
- if( zPath[i] ) i++;
+ if( zPath[i] ){
+ i++;
+ }else{
+ *pzErr = zPath;
+ return 0;
+ }
}else{
zKey = zPath;
for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){}
@@ -969,6 +982,7 @@ static JsonNode *jsonLookup(
){
const char *zErr = 0;
JsonNode *pNode = 0;
+ char *zMsg;
if( zPath==0 ) return 0;
if( zPath[0]!='$' ){
@@ -977,18 +991,17 @@ static JsonNode *jsonLookup(
}
zPath++;
pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr);
- return pNode;
+ if( zErr==0 ) return pNode;
lookup_err:
pParse->nErr++;
- if( zErr!=0 && pCtx!=0 ){
- char *z = jsonPathSyntaxError(zErr);
- if( z ){
- sqlite3_result_error(pCtx, z, -1);
- sqlite3_free(z);
- }else{
- sqlite3_result_error_nomem(pCtx);
- }
+ assert( zErr!=0 && pCtx!=0 );
+ zMsg = jsonPathSyntaxError(zErr);
+ if( zMsg ){
+ sqlite3_result_error(pCtx, zMsg, -1);
+ sqlite3_free(zMsg);
+ }else{
+ sqlite3_result_error_nomem(pCtx);
}
return 0;
}
@@ -1111,23 +1124,22 @@ static void jsonArrayLengthFunc(
JsonParse x; /* The parse */
sqlite3_int64 n = 0;
u32 i;
+ JsonNode *pNode;
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- if( x.nNode ){
- JsonNode *pNode;
- if( argc==2 ){
- const char *zPath = (const char*)sqlite3_value_text(argv[1]);
- pNode = jsonLookup(&x, zPath, 0, ctx);
- }else{
- pNode = x.aNode;
- }
- if( pNode==0 ){
- x.nErr = 1;
- }else if( pNode->eType==JSON_ARRAY ){
- assert( (pNode->jnFlags & JNODE_APPEND)==0 );
- for(i=1; i<=pNode->n; n++){
- i += jsonNodeSize(&pNode[i]);
- }
+ assert( x.nNode );
+ if( argc==2 ){
+ const char *zPath = (const char*)sqlite3_value_text(argv[1]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ }else{
+ pNode = x.aNode;
+ }
+ if( pNode==0 ){
+ x.nErr = 1;
+ }else if( pNode->eType==JSON_ARRAY ){
+ assert( (pNode->jnFlags & JNODE_APPEND)==0 );
+ for(i=1; i<=pNode->n; n++){
+ i += jsonNodeSize(&pNode[i]);
}
}
if( x.nErr==0 ) sqlite3_result_int64(ctx, n);
@@ -1240,17 +1252,16 @@ static void jsonRemoveFunc(
if( argc<1 ) return;
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- if( x.nNode ){
- for(i=1; i<(u32)argc; i++){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- if( zPath==0 ) goto remove_done;
- pNode = jsonLookup(&x, zPath, 0, ctx);
- if( x.nErr ) goto remove_done;
- if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
- }
- if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
- jsonReturnJson(x.aNode, ctx, 0);
- }
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i++){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ if( zPath==0 ) goto remove_done;
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) goto remove_done;
+ if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
+ }
+ if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
+ jsonReturnJson(x.aNode, ctx, 0);
}
remove_done:
jsonParseReset(&x);
@@ -1278,22 +1289,21 @@ static void jsonReplaceFunc(
return;
}
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- if( x.nNode ){
- for(i=1; i<(u32)argc; i+=2){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- pNode = jsonLookup(&x, zPath, 0, ctx);
- if( x.nErr ) goto replace_err;
- if( pNode ){
- pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->iVal = (u8)(i+1);
- }
- }
- if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
- }else{
- jsonReturnJson(x.aNode, ctx, argv);
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i+=2){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ if( x.nErr ) goto replace_err;
+ if( pNode ){
+ pNode->jnFlags |= (u8)JNODE_REPLACE;
+ pNode->iVal = (u8)(i+1);
}
}
+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+ sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ }else{
+ jsonReturnJson(x.aNode, ctx, argv);
+ }
replace_err:
jsonParseReset(&x);
}
@@ -1328,27 +1338,26 @@ static void jsonSetFunc(
return;
}
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- if( x.nNode ){
- for(i=1; i<(u32)argc; i+=2){
- zPath = (const char*)sqlite3_value_text(argv[i]);
- bApnd = 0;
- pNode = jsonLookup(&x, zPath, &bApnd, ctx);
- if( x.oom ){
- sqlite3_result_error_nomem(ctx);
- goto jsonSetDone;
- }else if( x.nErr ){
- goto jsonSetDone;
- }else if( pNode && (bApnd || bIsSet) ){
- pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->iVal = (u8)(i+1);
- }
- }
- if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
- }else{
- jsonReturnJson(x.aNode, ctx, argv);
+ assert( x.nNode );
+ for(i=1; i<(u32)argc; i+=2){
+ zPath = (const char*)sqlite3_value_text(argv[i]);
+ bApnd = 0;
+ pNode = jsonLookup(&x, zPath, &bApnd, ctx);
+ if( x.oom ){
+ sqlite3_result_error_nomem(ctx);
+ goto jsonSetDone;
+ }else if( x.nErr ){
+ goto jsonSetDone;
+ }else if( pNode && (bApnd || bIsSet) ){
+ pNode->jnFlags |= (u8)JNODE_REPLACE;
+ pNode->iVal = (u8)(i+1);
}
}
+ if( x.aNode[0].jnFlags & JNODE_REPLACE ){
+ sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ }else{
+ jsonReturnJson(x.aNode, ctx, argv);
+ }
jsonSetDone:
jsonParseReset(&x);
}
@@ -1367,19 +1376,18 @@ static void jsonTypeFunc(
){
JsonParse x; /* The parse */
const char *zPath;
+ JsonNode *pNode;
if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
- if( x.nNode ){
- JsonNode *pNode;
- if( argc==2 ){
- zPath = (const char*)sqlite3_value_text(argv[1]);
- pNode = jsonLookup(&x, zPath, 0, ctx);
- }else{
- pNode = x.aNode;
- }
- if( pNode ){
- sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
- }
+ assert( x.nNode );
+ if( argc==2 ){
+ zPath = (const char*)sqlite3_value_text(argv[1]);
+ pNode = jsonLookup(&x, zPath, 0, ctx);
+ }else{
+ pNode = x.aNode;
+ }
+ if( pNode ){
+ sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC);
}
jsonParseReset(&x);
}
@@ -1399,9 +1407,7 @@ static void jsonValidFunc(
int rc = 0;
UNUSED_PARAM(argc);
- if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0
- && x.nNode>0
- ){
+ if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){
rc = 1;
}
jsonParseReset(&x);
@@ -1754,15 +1760,6 @@ static int jsonEachFilter(
if( idxNum==0 ) return SQLITE_OK;
z = (const char*)sqlite3_value_text(argv[0]);
if( z==0 ) return SQLITE_OK;
- if( idxNum&2 ){
- zRoot = (const char*)sqlite3_value_text(argv[1]);
- if( zRoot==0 ) return SQLITE_OK;
- if( zRoot[0]!='$' ){
- sqlite3_free(cur->pVtab->zErrMsg);
- cur->pVtab->zErrMsg = jsonPathSyntaxError(zRoot);
- return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
- }
- }
n = sqlite3_value_bytes(argv[0]);
p->zJson = sqlite3_malloc64( n+1 );
if( p->zJson==0 ) return SQLITE_NOMEM;
@@ -1783,12 +1780,18 @@ static int jsonEachFilter(
JsonNode *pNode;
if( idxNum==3 ){
const char *zErr = 0;
+ 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);
- pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
- if( p->sParse.nErr ){
+ if( zRoot[0]!='$' ){
+ zErr = zRoot;
+ }else{
+ pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr);
+ }
+ if( zErr ){
sqlite3_free(cur->pVtab->zErrMsg);
cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr);
jsonEachCursorReset(p);
@@ -1815,7 +1818,7 @@ static int jsonEachFilter(
p->iEnd = p->i+1;
}
}
- return p->sParse.oom ? SQLITE_NOMEM : SQLITE_OK;
+ return SQLITE_OK;
}
/* The methods of the json_each virtual table */