/ Check-in [4aa49656]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Initial implementation of json_set() and json_insert().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | json
Files: files | file ages | folders
SHA1: 4aa49656d98e2894f2faa8963f79462ee6165d40
User & Date: drh 2015-08-18 02:28:03
Context
2015-08-18
12:59
Comment clarification. No changes to code. check-in: 71a96695 user: drh tags: json
02:28
Initial implementation of json_set() and json_insert(). check-in: 4aa49656 user: drh tags: json
2015-08-17
21:22
Initial implementation of json_replace(). check-in: 3c4bee65 user: drh tags: json
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/misc/json.c.

    27     27   #include <stdlib.h>
    28     28   
    29     29   /* Unsigned integer types */
    30     30   typedef sqlite3_uint64 u64;
    31     31   typedef unsigned int u32;
    32     32   typedef unsigned char u8;
    33     33   
           34  +/* Objects */
           35  +typedef struct Json Json;
           36  +typedef struct JsonNode JsonNode;
           37  +typedef struct JsonParse JsonParse;
           38  +
    34     39   /* An instance of this object represents a JSON string
    35     40   ** under construction.  Really, this is a generic string accumulator
    36     41   ** that can be and is used to create strings other than JSON.
    37     42   */
    38         -typedef struct Json Json;
    39     43   struct Json {
    40     44     sqlite3_context *pCtx;   /* Function context - put error messages here */
    41     45     char *zBuf;              /* Append JSON content here */
    42     46     u64 nAlloc;              /* Bytes of storage available in zBuf[] */
    43     47     u64 nUsed;               /* Bytes of zBuf[] currently used */
    44     48     u8 bStatic;              /* True if zBuf is static space */
    45     49     u8 bErr;                 /* True if an error has been encountered */
................................................................................
    66     70   
    67     71   /* Bit values for the JsonNode.jnFlag field
    68     72   */
    69     73   #define JNODE_RAW     0x01         /* Content is raw, not JSON encoded */
    70     74   #define JNODE_ESCAPE  0x02         /* Content is text with \ escapes */
    71     75   #define JNODE_REMOVE  0x04         /* Do not output */
    72     76   #define JNODE_REPLACE 0x08         /* Replace with JsonNode.iVal */
           77  +#define JNODE_APPEND  0x10         /* More ARRAY/OBJECT entries at u.iAppend */
    73     78   
    74     79   
    75     80   /* A single node of parsed JSON
    76     81   */
    77         -typedef struct JsonNode JsonNode;
    78     82   struct JsonNode {
    79     83     u8 eType;              /* One of the JSON_ type values */
    80     84     u8 jnFlags;            /* JNODE flags */
    81     85     u8 iVal;               /* Replacement value when JNODE_REPLACE */
    82     86     u32 n;                 /* Bytes of content, or number of sub-nodes */
    83         -  const char *zJContent; /* JSON content */
           87  +  union {
           88  +    const char *zJContent; /* JSON content */
           89  +    u32 iAppend;           /* Appended content */
           90  +  } u;
    84     91   };
    85     92   
    86     93   /* A completely parsed JSON string
    87     94   */
    88         -typedef struct JsonParse JsonParse;
    89     95   struct JsonParse {
    90     96     u32 nNode;         /* Number of slots of aNode[] used */
    91     97     u32 nAlloc;        /* Number of slots of aNode[] allocated */
    92     98     JsonNode *aNode;   /* Array of nodes containing the parse */
    93     99     const char *zJson; /* Original JSON string */
    94    100     u8 oom;            /* Set to true if out of memory */
    95    101   };
    96    102   
    97    103   /*
    98    104   ** Return the number of consecutive JsonNode slots need to represent
    99    105   ** the parsed JSON at pNode.  The minimum answer is 1.  For ARRAY and
   100    106   ** OBJECT types, the number might be larger.
          107  +**
          108  +** Appended elements are not counted.  The value returned is the number
          109  +** by which the JsonNode counter should increment in order to go to the
          110  +** next peer value.
   101    111   */
   102    112   static u32 jsonSize(JsonNode *pNode){
   103    113     return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1;
   104    114   }
   105    115   
   106    116   /* Set the Json object to an empty string
   107    117   */
................................................................................
   272    282   }
   273    283   
   274    284   /*
   275    285   ** Convert the JsonNode pNode into a pure JSON string and
   276    286   ** append to pOut.  Subsubstructure is also included.  Return
   277    287   ** the number of JsonNode objects that are encoded.
   278    288   */
   279         -static int jsonRenderNode(
          289  +static void jsonRenderNode(
   280    290     JsonNode *pNode,               /* The node to render */
   281    291     Json *pOut,                    /* Write JSON here */
   282    292     sqlite3_value **aReplace       /* Replacement values */
   283    293   ){
   284         -  u32 j = 1;
   285    294     switch( pNode->eType ){
   286    295       case JSON_NULL: {
   287    296         jsonAppendRaw(pOut, "null", 4);
   288    297         break;
   289    298       }
   290    299       case JSON_TRUE: {
   291    300         jsonAppendRaw(pOut, "true", 4);
................................................................................
   293    302       }
   294    303       case JSON_FALSE: {
   295    304         jsonAppendRaw(pOut, "false", 5);
   296    305         break;
   297    306       }
   298    307       case JSON_STRING: {
   299    308         if( pNode->jnFlags & JNODE_RAW ){
   300         -        jsonAppendString(pOut, pNode->zJContent, pNode->n);
          309  +        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
   301    310           break;
   302    311         }
   303    312         /* Fall through into the next case */
   304    313       }
   305    314       case JSON_REAL:
   306    315       case JSON_INT: {
   307         -      jsonAppendRaw(pOut, pNode->zJContent, pNode->n);
          316  +      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
   308    317         break;
   309    318       }
   310    319       case JSON_ARRAY: {
          320  +      u32 j = 1;
   311    321         jsonAppendChar(pOut, '[');
   312         -      while( j<=pNode->n ){
   313         -        if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
   314         -          if( pNode[j].jnFlags & JNODE_REPLACE ){
          322  +      for(;;){
          323  +        while( j<=pNode->n ){
          324  +          if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
          325  +            if( pNode[j].jnFlags & JNODE_REPLACE ){
          326  +              jsonAppendSeparator(pOut);
          327  +              jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
          328  +            }
          329  +          }else{
   315    330               jsonAppendSeparator(pOut);
   316         -            jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
          331  +            jsonRenderNode(&pNode[j], pOut, aReplace);
   317    332             }
   318    333             j += jsonSize(&pNode[j]);
   319         -        }else{
   320         -          jsonAppendSeparator(pOut);
   321         -          j += jsonRenderNode(&pNode[j], pOut, aReplace);
   322    334           }
          335  +        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
          336  +        pNode = &pNode[pNode->u.iAppend];
          337  +        j = 1;
   323    338         }
   324    339         jsonAppendChar(pOut, ']');
   325    340         break;
   326    341       }
   327    342       case JSON_OBJECT: {
          343  +      u32 j = 1;
   328    344         jsonAppendChar(pOut, '{');
   329         -      while( j<=pNode->n ){
   330         -        if( pNode[j+1].jnFlags & JNODE_REMOVE ){
   331         -          j += 1 + jsonSize(&pNode[j+1]);
   332         -        }else{
   333         -          jsonAppendSeparator(pOut);
   334         -          jsonRenderNode(&pNode[j], pOut, aReplace);
   335         -          jsonAppendChar(pOut, ':');
   336         -          if( pNode[j+1].jnFlags & JNODE_REPLACE ){
   337         -            jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
   338         -            j += 1 + jsonSize(&pNode[j+1]);
   339         -          }else{
   340         -            j += 1 + jsonRenderNode(&pNode[j+1], pOut, aReplace);
          345  +      for(;;){
          346  +        while( j<=pNode->n ){
          347  +          if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){
          348  +            jsonAppendSeparator(pOut);
          349  +            jsonRenderNode(&pNode[j], pOut, aReplace);
          350  +            jsonAppendChar(pOut, ':');
          351  +            if( pNode[j+1].jnFlags & JNODE_REPLACE ){
          352  +              jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
          353  +            }else{
          354  +              jsonRenderNode(&pNode[j+1], pOut, aReplace);
          355  +            }
   341    356             }
          357  +          j += 1 + jsonSize(&pNode[j+1]);
   342    358           }
          359  +        if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
          360  +        pNode = &pNode[pNode->u.iAppend];
          361  +        j = 1;
   343    362         }
   344    363         jsonAppendChar(pOut, '}');
   345    364         break;
   346    365       }
   347    366     }
   348         -  return j;
   349    367   }
   350    368   
   351    369   /*
   352    370   ** Make the JsonNode the return value of the function.
   353    371   */
   354    372   static void jsonReturn(
   355    373     JsonNode *pNode,            /* Node to return */
................................................................................
   366    384         break;
   367    385       }
   368    386       case JSON_FALSE: {
   369    387         sqlite3_result_int(pCtx, 0);
   370    388         break;
   371    389       }
   372    390       case JSON_REAL: {
   373         -      double r = strtod(pNode->zJContent, 0);
          391  +      double r = strtod(pNode->u.zJContent, 0);
   374    392         sqlite3_result_double(pCtx, r);
   375    393         break;
   376    394       }
   377    395       case JSON_INT: {
   378    396         sqlite3_int64 i = 0;
   379         -      const char *z = pNode->zJContent;
          397  +      const char *z = pNode->u.zJContent;
   380    398         if( z[0]=='-' ){ z++; }
   381    399         while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
   382         -      if( pNode->zJContent[0]=='-' ){ i = -i; }
          400  +      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
   383    401         sqlite3_result_int64(pCtx, i);
   384    402         break;
   385    403       }
   386    404       case JSON_STRING: {
   387    405         if( pNode->jnFlags & JNODE_RAW ){
   388         -        sqlite3_result_text(pCtx, pNode->zJContent, pNode->n, SQLITE_TRANSIENT);
          406  +        sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
          407  +                            SQLITE_TRANSIENT);
   389    408         }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
   390    409           /* JSON formatted without any backslash-escapes */
   391         -        sqlite3_result_text(pCtx, pNode->zJContent+1, pNode->n-2,
          410  +        sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
   392    411                               SQLITE_TRANSIENT);
   393    412         }else{
   394    413           /* Translate JSON formatted string into raw text */
   395    414           u32 i;
   396    415           u32 n = pNode->n;
   397         -        const char *z = pNode->zJContent;
          416  +        const char *z = pNode->u.zJContent;
   398    417           char *zOut;
   399    418           u32 j;
   400    419           zOut = sqlite3_malloc( n+1 );
   401    420           if( zOut==0 ){
   402    421             sqlite3_result_error_nomem(pCtx);
   403    422             break;
   404    423           }
................................................................................
   496    515       pParse->aNode = pNew;
   497    516     }
   498    517     p = &pParse->aNode[pParse->nNode];
   499    518     p->eType = (u8)eType;
   500    519     p->jnFlags = 0;
   501    520     p->iVal = 0;
   502    521     p->n = n;
   503         -  p->zJContent = zContent;
          522  +  p->u.zJContent = zContent;
   504    523     return pParse->nNode++;
   505    524   }
   506    525   
   507    526   /*
   508    527   ** Parse a single JSON value which begins at pParse->zJson[i].  Return the
   509    528   ** index of the first character past the end of the value parsed.
   510    529   **
................................................................................
   660    679       pParse->nNode = 0;
   661    680       pParse->nAlloc = 0;
   662    681       return 1;
   663    682     }
   664    683     return 0;
   665    684   }
   666    685   
          686  +/* forward declaration */
          687  +static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*);
          688  +
   667    689   /*
   668    690   ** Search along zPath to find the node specified.  Return a pointer
   669    691   ** to that node, or NULL if zPath is malformed or if there is no such
   670    692   ** node.
          693  +**
          694  +** If pApnd!=0, then try to append new nodes to complete zPath if it is
          695  +** possible to do so and if no existing node corresponds to zPath.  If
          696  +** new nodes are appended *pApnd is set to 1.
   671    697   */
   672         -static JsonNode *jsonLookup(JsonNode *pRoot, const char *zPath){
   673         -  u32 i, j;
          698  +static JsonNode *jsonLookup(
          699  +  JsonParse *pParse,      /* The JSON to search */
          700  +  u32 iRoot,              /* Begin the search at this node */
          701  +  const char *zPath,      /* The path to search */
          702  +  int *pApnd              /* Append nodes to complete path if not NULL */
          703  +){
          704  +  u32 i, j, k;
          705  +  JsonNode *pRoot = &pParse->aNode[iRoot];
   674    706     if( zPath[0]==0 ) return pRoot;
   675    707     if( zPath[0]=='.' ){
   676    708       if( pRoot->eType!=JSON_OBJECT ) return 0;
   677    709       zPath++;
   678    710       for(i=0; isalnum(zPath[i]); i++){}
   679    711       if( i==0 ) return 0;
   680    712       j = 1;
   681         -    while( j<=pRoot->n ){
   682         -      if( pRoot[j].n==i+2
   683         -       && strncmp(&pRoot[j].zJContent[1],zPath,i)==0
   684         -      ){
   685         -        return jsonLookup(&pRoot[j+1], &zPath[i]);
          713  +    for(;;){
          714  +      while( j<=pRoot->n ){
          715  +        if( pRoot[j].n==i+2
          716  +         && strncmp(&pRoot[j].u.zJContent[1],zPath,i)==0
          717  +        ){
          718  +          return jsonLookup(pParse, iRoot+j+1, &zPath[i], pApnd);
          719  +        }
          720  +        j++;
          721  +        j += jsonSize(&pRoot[j]);
   686    722         }
   687         -      j++;
   688         -      j += jsonSize(&pRoot[j]);
          723  +      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
          724  +      iRoot += pRoot->u.iAppend;
          725  +      pRoot = &pParse->aNode[iRoot];
          726  +      j = 1;
          727  +    }
          728  +    if( pApnd ){
          729  +      k = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
          730  +      pRoot->u.iAppend = k - iRoot;
          731  +      pRoot->jnFlags |= JNODE_APPEND;
          732  +      k = jsonParseAddNode(pParse, JSON_STRING, i, zPath);
          733  +      if( !pParse->oom ) pParse->aNode[k].jnFlags |= JNODE_RAW;
          734  +      zPath += i;
          735  +      return jsonLookupAppend(pParse, zPath, pApnd);
   689    736       }
   690    737     }else if( zPath[0]=='[' && isdigit(zPath[1]) ){
   691    738       if( pRoot->eType!=JSON_ARRAY ) return 0;
   692    739       i = 0;
   693    740       zPath++;
   694    741       while( isdigit(zPath[0]) ){
   695    742         i = i + zPath[0] - '0';
   696    743         zPath++;
   697    744       }
   698    745       if( zPath[0]!=']' ) return 0;
   699    746       zPath++;
   700    747       j = 1;
   701         -    while( i>0 && j<=pRoot->n ){
   702         -      j += jsonSize(&pRoot[j]);
   703         -      i--;
          748  +    for(;;){
          749  +      while( i>0 && j<=pRoot->n ){
          750  +        j += jsonSize(&pRoot[j]);
          751  +        i--;
          752  +      }
          753  +      if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
          754  +      iRoot += pRoot->u.iAppend;
          755  +      pRoot = &pParse->aNode[iRoot];
          756  +      j = 1;
   704    757       }
   705    758       if( j<=pRoot->n ){
   706         -      return jsonLookup(&pRoot[j], zPath);
          759  +      return jsonLookup(pParse, iRoot+j, zPath, pApnd);
          760  +    }
          761  +    if( i==0 && pApnd ){
          762  +      k = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
          763  +      pRoot->u.iAppend = k - iRoot;
          764  +      pRoot->jnFlags |= JNODE_APPEND;
          765  +      return jsonLookupAppend(pParse, zPath, pApnd);
   707    766       }
   708    767     }
   709    768     return 0;
   710    769   }
          770  +
          771  +/*
          772  +** Append content to pParse that will complete zPath.
          773  +*/
          774  +static JsonNode *jsonLookupAppend(
          775  +  JsonParse *pParse,     /* Append content to the JSON parse */
          776  +  const char *zPath,     /* Description of content to append */
          777  +  int *pApnd             /* Set this flag to 1 */
          778  +){
          779  +  *pApnd = 1;
          780  +  if( zPath[0]==0 ){
          781  +    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
          782  +    return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1];
          783  +  }
          784  +  if( zPath[0]=='.' ){
          785  +    jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
          786  +  }else if( strncmp(zPath,"[0]",3)==0 ){
          787  +    jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
          788  +  }else{
          789  +    return 0;
          790  +  }
          791  +  if( pParse->oom ) return 0;
          792  +  return jsonLookup(pParse, pParse->nNode-1, zPath, pApnd);
          793  +}
          794  +
   711    795   
   712    796   /****************************************************************************
   713    797   ** SQL functions used for testing and debugging
   714    798   ****************************************************************************/
   715    799   
   716    800   #ifdef SQLITE_DEBUG
   717    801   /*
................................................................................
   732    816     assert( argc==1 );
   733    817     if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
   734    818     jsonInit(&s, context);
   735    819     for(i=0; i<x.nNode; i++){
   736    820       sqlite3_snprintf(sizeof(zBuf), zBuf, "node %3u: %7s n=%d\n",
   737    821                        i, jsonType[x.aNode[i].eType], x.aNode[i].n);
   738    822       jsonAppend(&s, zBuf);
   739         -    if( x.aNode[i].zJContent!=0 ){
          823  +    if( x.aNode[i].u.zJContent!=0 ){
   740    824         jsonAppendRaw(&s, "    text: ", 10);
   741         -      jsonAppendRaw(&s, x.aNode[i].zJContent, x.aNode[i].n);
          825  +      jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
   742    826         jsonAppendRaw(&s, "\n", 1);
   743    827       }
   744    828     }
   745    829     sqlite3_free(x.aNode);
   746    830     jsonResult(&s);
   747    831   }
   748    832   
................................................................................
   828    912       zPath++;
   829    913     }else{
   830    914       zPath = 0;
   831    915     }
   832    916     if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0]))==0 ){
   833    917       if( x.nNode ){
   834    918         JsonNode *pNode = x.aNode;
   835         -      if( zPath ) pNode = jsonLookup(pNode, zPath);
          919  +      if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
   836    920         if( pNode->eType==JSON_ARRAY ){
          921  +        assert( (pNode->jnFlags & JNODE_APPEND)==0 );
   837    922           for(i=1; i<=pNode->n; n++){
   838    923             i += jsonSize(&pNode[i]);
   839    924           }
   840    925         }
   841    926       }
   842    927       sqlite3_free(x.aNode);
   843    928     }
................................................................................
   860    945     const char *zPath;
   861    946     assert( argc==2 );
   862    947     zPath = (const char*)sqlite3_value_text(argv[1]);
   863    948     if( zPath==0 ) return;
   864    949     if( zPath[0]!='$' ) return;
   865    950     zPath++;
   866    951     if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
   867         -  pNode = jsonLookup(x.aNode, zPath);
          952  +  pNode = jsonLookup(&x, 0, zPath, 0);
   868    953     if( pNode ){
   869    954       jsonReturn(pNode, context, 0);
   870    955     }
   871    956     sqlite3_free(x.aNode);
   872    957   }
   873    958   
   874    959   /*
................................................................................
   931   1016     if( argc<1 ) return;
   932   1017     if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
   933   1018     if( x.nNode ){
   934   1019       for(i=1; i<argc; i++){
   935   1020         zPath = (const char*)sqlite3_value_text(argv[i]);
   936   1021         if( zPath==0 ) continue;
   937   1022         if( zPath[0]!='$' ) continue;
   938         -      pNode = jsonLookup(x.aNode, &zPath[1]);
         1023  +      pNode = jsonLookup(&x, 0, &zPath[1], 0);
   939   1024         if( pNode ) pNode->jnFlags |= JNODE_REMOVE;
   940   1025       }
   941   1026       if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){
   942   1027         jsonReturn(x.aNode, context, 0);
   943   1028       }
   944   1029     }
   945   1030     sqlite3_free(x.aNode);
................................................................................
   969   1054     }
   970   1055     if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
   971   1056     if( x.nNode ){
   972   1057       for(i=1; i<argc; i+=2){
   973   1058         zPath = (const char*)sqlite3_value_text(argv[i]);
   974   1059         if( zPath==0 ) continue;
   975   1060         if( zPath[0]!='$' ) continue;
   976         -      pNode = jsonLookup(x.aNode, &zPath[1]);
         1061  +      pNode = jsonLookup(&x, 0, &zPath[1], 0);
   977   1062         if( pNode ){
   978   1063           pNode->jnFlags |= JNODE_REPLACE;
   979   1064           pNode->iVal = i+1;
   980   1065         }
         1066  +    }
         1067  +    if( x.aNode[0].jnFlags & JNODE_REPLACE ){
         1068  +      sqlite3_result_value(context, argv[x.aNode[0].iVal]);
         1069  +    }else{
         1070  +      jsonReturn(x.aNode, context, argv);
         1071  +    }
         1072  +  }
         1073  +  sqlite3_free(x.aNode);
         1074  +}
         1075  +/*
         1076  +** json_set(JSON, PATH, VALUE, ...)
         1077  +**
         1078  +** Set the value at PATH to VALUE.  Create the PATH if it does not already
         1079  +** exist.  Overwrite existing values that do exist.
         1080  +** If JSON is ill-formed, return NULL.
         1081  +**
         1082  +** json_insert(JSON, PATH, VALUE, ...)
         1083  +**
         1084  +** Create PATH and initialize it to VALUE.  If PATH already exists, this
         1085  +** routine is a no-op.  If JSON is ill-formed, return NULL.
         1086  +*/
         1087  +static void jsonSetFunc(
         1088  +  sqlite3_context *context,
         1089  +  int argc,
         1090  +  sqlite3_value **argv
         1091  +){
         1092  +  JsonParse x;          /* The parse */
         1093  +  JsonNode *pNode;
         1094  +  const char *zPath;
         1095  +  u32 i;
         1096  +  int bApnd;
         1097  +  int bIsSet = *(int*)sqlite3_user_data(context);
         1098  +
         1099  +  if( argc<1 ) return;
         1100  +  if( (argc&1)==0 ) {
         1101  +    sqlite3_result_error(context,
         1102  +                         "json_set() needs an odd number of arguments", -1);
         1103  +    return;
         1104  +  }
         1105  +  if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
         1106  +  if( x.nNode ){
         1107  +    for(i=1; i<argc; i+=2){
         1108  +      zPath = (const char*)sqlite3_value_text(argv[i]);
         1109  +      if( zPath==0 ) continue;
         1110  +      if( zPath[0]!='$' ) continue;
         1111  +      bApnd = 0;
         1112  +      pNode = jsonLookup(&x, 0, &zPath[1], &bApnd);
         1113  +      if( pNode && (bApnd || bIsSet) ){
         1114  +        pNode->jnFlags |= JNODE_REPLACE;
         1115  +        pNode->iVal = i+1;
         1116  +      }
   981   1117       }
   982   1118       if( x.aNode[0].jnFlags & JNODE_REPLACE ){
   983   1119         sqlite3_result_value(context, argv[x.aNode[0].iVal]);
   984   1120       }else{
   985   1121         jsonReturn(x.aNode, context, argv);
   986   1122       }
   987   1123     }
................................................................................
  1010   1146       zPath++;
  1011   1147     }else{
  1012   1148       zPath = 0;
  1013   1149     }
  1014   1150     if( jsonParse(&x, (const char*)sqlite3_value_text(argv[0])) ) return;
  1015   1151     if( x.nNode ){
  1016   1152       JsonNode *pNode = x.aNode;
  1017         -    if( zPath ) pNode = jsonLookup(pNode, zPath);
         1153  +    if( zPath ) pNode = jsonLookup(&x, 0, zPath, 0);
  1018   1154       sqlite3_result_text(context, jsonType[pNode->eType], -1, SQLITE_STATIC);
  1019   1155     }
  1020   1156     sqlite3_free(x.aNode);
  1021   1157   }
  1022   1158   
  1023   1159   #ifdef _WIN32
  1024   1160   __declspec(dllexport)
................................................................................
  1029   1165     const sqlite3_api_routines *pApi
  1030   1166   ){
  1031   1167     int rc = SQLITE_OK;
  1032   1168     int i;
  1033   1169     static const struct {
  1034   1170        const char *zName;
  1035   1171        int nArg;
         1172  +     int flag;
  1036   1173        void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
  1037   1174     } aFunc[] = {
  1038         -    { "json_array",          -1,    jsonArrayFunc         },
  1039         -    { "json_array_length",    1,    jsonArrayLengthFunc   },
  1040         -    { "json_array_length",    2,    jsonArrayLengthFunc   },
  1041         -    { "json_extract",         2,    jsonExtractFunc       },
  1042         -    { "json_object",         -1,    jsonObjectFunc        },
  1043         -    { "json_remove",         -1,    jsonRemoveFunc        },
  1044         -    { "json_replace",        -1,    jsonReplaceFunc       },
  1045         -    { "json_type",            1,    jsonTypeFunc          },
  1046         -    { "json_type",            2,    jsonTypeFunc          },
         1175  +    { "json_array",          -1, 0,   jsonArrayFunc         },
         1176  +    { "json_array_length",    1, 0,   jsonArrayLengthFunc   },
         1177  +    { "json_array_length",    2, 0,   jsonArrayLengthFunc   },
         1178  +    { "json_extract",         2, 0,   jsonExtractFunc       },
         1179  +    { "json_insert",         -1, 0,   jsonSetFunc           },
         1180  +    { "json_object",         -1, 0,   jsonObjectFunc        },
         1181  +    { "json_remove",         -1, 0,   jsonRemoveFunc        },
         1182  +    { "json_replace",        -1, 0,   jsonReplaceFunc       },
         1183  +    { "json_set",            -1, 1,   jsonSetFunc           },
         1184  +    { "json_type",            1, 0,   jsonTypeFunc          },
         1185  +    { "json_type",            2, 0,   jsonTypeFunc          },
  1047   1186   
  1048   1187   #if SQLITE_DEBUG
  1049   1188       /* DEBUG and TESTING functions */
  1050         -    { "json_parse",           1,    jsonParseFunc     },
  1051         -    { "json_test1",           1,    jsonTest1Func     },
  1052         -    { "json_nodecount",       1,    jsonNodeCountFunc },
         1189  +    { "json_parse",           1, 0,   jsonParseFunc         },
         1190  +    { "json_test1",           1, 0,   jsonTest1Func         },
         1191  +    { "json_nodecount",       1, 0,   jsonNodeCountFunc     },
  1053   1192   #endif
  1054   1193     };
  1055   1194     SQLITE_EXTENSION_INIT2(pApi);
  1056   1195     (void)pzErrMsg;  /* Unused parameter */
  1057   1196     for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
  1058   1197       rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
  1059         -                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
         1198  +                                 SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
         1199  +                                 (void*)&aFunc[i].flag,
  1060   1200                                    aFunc[i].xFunc, 0, 0);
  1061   1201     }
  1062   1202     return rc;
  1063   1203   }