1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-09 14:21:03 +03:00

Fix the PG-compatible -> and ->> path parsing.

FossilOrigin-Name: 22d5138315fb77eeea1c7e66ccc4190bcae18d058a99aa37ddd119e54b52f723
This commit is contained in:
drh
2022-01-11 18:01:17 +00:00
parent 875912c246
commit aa97b57b11
3 changed files with 32 additions and 29 deletions

View File

@@ -1549,36 +1549,39 @@ static void jsonExtractFunc(
/* With a single PATH argument */
zPath = (const char*)sqlite3_value_text(argv[1]);
if( zPath==0 ) return;
if( zPath[0]!='$' && (flags & JSON_ABPATH)!=0 ){
/* The -> and ->> operators accept abbreviated PATH arguments. This
** is mostly for compatibility with PostgreSQL, but also for convenience.
**
** NUMBER ==> $[NUMBER] // PG compatible
** LABEL ==> $.LABEL // PG compatible
** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
*/
jsonInit(&jx, ctx);
if( sqlite3Isdigit(zPath[0]) ){
jsonAppendRaw(&jx, "$[", 2);
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
jsonAppendRaw(&jx, "]", 2);
if( flags & JSON_ABPATH ){
if( zPath[0]!='$' ){
/* The -> and ->> operators accept abbreviated PATH arguments. This
** is mostly for compatibility with PostgreSQL, but also for
** convenience.
**
** NUMBER ==> $[NUMBER] // PG compatible
** LABEL ==> $.LABEL // PG compatible
** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience
*/
jsonInit(&jx, ctx);
if( sqlite3Isdigit(zPath[0]) ){
jsonAppendRaw(&jx, "$[", 2);
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
jsonAppendRaw(&jx, "]", 2);
}else{
jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='['));
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
jsonAppendChar(&jx, 0);
}
pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
jsonReset(&jx);
}else{
jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='['));
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
jsonAppendChar(&jx, 0);
pNode = jsonLookup(p, zPath, 0, ctx);
}
if( jx.bErr==0 ){
pNode = jsonLookup(p, jx.zBuf, 0, ctx);
if( pNode==0 ){
/* No-op. jsonLookup will have left an error for us */
}else if( flags & JSON_JSON ){
if( pNode ){
if( flags & JSON_JSON ){
jsonReturnJson(pNode, ctx, 0);
}else{
jsonReturn(pNode, ctx, 0);
sqlite3_result_subtype(ctx, 0);
}
}
jsonReset(&jx);
}else{
pNode = jsonLookup(p, zPath, 0, ctx);
if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0);