aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2023-09-30 14:34:39 +0000
committerdrh <>2023-09-30 14:34:39 +0000
commit7e86d3fc6961dc64a45cfefd6ceeea375167ffc4 (patch)
tree2141420f72ecbf5863bc7ad2205e44ea27c9ba92 /src
parent5736ba5ac3a2c4e4a9735f5b35ce0f4dc76c5f14 (diff)
downloadsqlite-7e86d3fc6961dc64a45cfefd6ceeea375167ffc4.tar.gz
sqlite-7e86d3fc6961dc64a45cfefd6ceeea375167ffc4.zip
Finish adding jsonb_ versions for all JSON routines that return JSON text.
FossilOrigin-Name: 6daa7b69695e1b68dba317abbcad4d0205c91963d4a9eb2d595a3ec10fa0fdf4
Diffstat (limited to 'src')
-rw-r--r--src/json.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/json.c b/src/json.c
index a790157a5..0089584e6 100644
--- a/src/json.c
+++ b/src/json.c
@@ -724,6 +724,8 @@ static void jsonAppendSqlValue(
}
}
+/* Forward reference */
+static void jsonReturnStringAsBlob(JsonString*);
/* Make the text in p (which is probably a generated JSON text string)
** the result of the SQL function.
@@ -732,7 +734,10 @@ static void jsonAppendSqlValue(
*/
static void jsonReturnString(JsonString *p){
if( p->bErr==0 ){
- if( p->bStatic ){
+ int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx));
+ if( flags & JSON_BLOB ){
+ jsonReturnStringAsBlob(p);
+ }else if( p->bStatic ){
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
SQLITE_TRANSIENT, SQLITE_UTF8);
}else if( jsonForceRCStr(p) ){
@@ -3145,6 +3150,25 @@ static int jsonConvertTextToBlob(
return 0;
}
+/*
+** The input string pStr is a well-formed JSON text string. Convert
+** this into the JSONB format and make it the return value of the
+** SQL function.
+*/
+static void jsonReturnStringAsBlob(JsonString *pStr){
+ JsonParse px;
+ memset(&px, 0, sizeof(px));
+ px.zJson = pStr->zBuf;
+ px.nJson = pStr->nUsed;
+ (void)jsonTranslateTextValueToBlob(&px, 0);
+ if( px.oom ){
+ sqlite3_free(px.aBlob);
+ sqlite3_result_error_nomem(pStr->pCtx);
+ }else{
+ sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, sqlite3_free);
+ }
+}
+
/* The byte at index i is a node type-code. This routine
** determines the payload size for that node and writes that
** payload size in to *pSz. It returns the offset from i to the
@@ -4860,11 +4884,16 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
if( pStr ){
+ int flags;
pStr->pCtx = ctx;
jsonAppendChar(pStr, ']');
+ flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
if( pStr->bErr ){
if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
assert( pStr->bStatic );
+ }else if( flags & JSON_BLOB ){
+ jsonReturnStringAsBlob(pStr);
+ return;
}else if( isFinal ){
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
pStr->bStatic ? SQLITE_TRANSIENT :
@@ -4970,10 +4999,16 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){
JsonString *pStr;
pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0);
if( pStr ){
+ int flags;
jsonAppendChar(pStr, '}');
+ pStr->pCtx = ctx;
+ flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx));
if( pStr->bErr ){
if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
assert( pStr->bStatic );
+ }else if( flags & JSON_BLOB ){
+ jsonReturnStringAsBlob(pStr);
+ return;
}else if( isFinal ){
sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed,
pStr->bStatic ? SQLITE_TRANSIENT :
@@ -5557,6 +5592,7 @@ void sqlite3RegisterJsonFunctions(void){
JFUNCTION(json, 1, 0, jsonRemoveFunc),
JFUNCTION(jsonb, 1, JSON_BLOB, jsonbFunc),
JFUNCTION(json_array, -1, 0, jsonArrayFunc),
+ JFUNCTION(jsonb_array, -1, JSON_BLOB, jsonArrayFunc),
JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc),
JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc),
JFUNCTION(json_error_position,1, 0, jsonErrorFunc),
@@ -5567,6 +5603,7 @@ void sqlite3RegisterJsonFunctions(void){
JFUNCTION(json_insert, -1, 0, jsonSetFunc),
JFUNCTION(jsonb_insert, -1, JSON_BLOB, jsonSetFunc),
JFUNCTION(json_object, -1, 0, jsonObjectFunc),
+ JFUNCTION(jsonb_object, -1, JSON_BLOB, jsonObjectFunc),
JFUNCTION(json_patch, 2, 0, jsonPatchFunc),
JFUNCTION(jsonb_patch, 2, JSON_BLOB, jsonPatchFunc),
JFUNCTION(json_quote, 1, 0, jsonQuoteFunc),
@@ -5587,8 +5624,14 @@ void sqlite3RegisterJsonFunctions(void){
WAGGREGATE(json_group_array, 1, 0, 0,
jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
+ WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0,
+ jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
+ SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
WAGGREGATE(json_group_object, 2, 0, 0,
jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
+ SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
+ WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0,
+ jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC)
};
sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));