UnQL

Check-in [e049952168]
Login

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

Overview
Comment:Add support for the [] operator on objects. Using the [] operator with an array or string does not work yet.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e0499521683ba6f11cf7393097cb9b45e91f16c5
User & Date: dan 2011-07-16 12:26:25
Original Comment: Add support for the [] operator on objects. Using the [] operator with an array or string does not work yet.
Context
2011-07-16
14:53
Provide an implementation for the "in" operator. check-in: 4f893cfaf7 user: drh tags: trunk
12:26
Add support for the [] operator on objects. Using the [] operator with an array or string does not work yet. check-in: e049952168 user: dan tags: trunk
12:22
Add parsing of "in" and "WITHIN" operators. Missing implementions. check-in: a8abdbeadb user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

225
226
227
228
229
230
231


























232
233
234
235
236
237
238
...
242
243
244
245
246
247
248

249
250
251


252













253
254
255
256





257
258
259



260
261


262





263
264
265
266
267
268
269
270
271
272
273
274
** Allocate a NULL JSON object.
*/
static JsonNode *nullJson(void){
  JsonNode *pRes = xjd1JsonNew(0);
  if( pRes ) pRes->eJType = XJD1_NULL;
  return pRes;
}



























/*
** Evaluate an expression.  Return the result as a JSON object.
**
** The caller must free the returned JSON by a call xjdJsonFree().
*/
JsonNode *xjd1ExprEval(Expr *p){
................................................................................
  JsonNode *pJLeft, *pJRight;

  if( p==0 ) return nullJson();
  switch( p->eType ){
    case TK_JVALUE: {
      return xjd1JsonRef(p->u.json.p);
    }

    case TK_DOT: {
      JsonNode *pBase = xjd1ExprEval(p->u.lvalue.pLeft);
      JsonStructElem *pElem;


      pRes = 0;













      if( pBase && pBase->eJType==XJD1_STRUCT ){
        for(pElem=pBase->u.st.pFirst; pElem; pElem=pElem->pNext){
          if( strcmp(pElem->zLabel, p->u.lvalue.zId)==0 ){
            pRes = xjd1JsonRef(pElem->pValue);





            break;
          }
        }



      }
      xjd1JsonFree(pBase);


      if( pRes==0 ) pRes = nullJson();





      return pRes;
    }
    case TK_LB: {
      return nullJson();   /* TBD */
    }
    case TK_ID: {
      if( p->pQuery ){
        return xjd1QueryDoc(p->pQuery, p->u.id.zId);
      }else{
        return xjd1StmtDoc(p->pStmt, p->u.id.zId);
      }
    }







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>


<
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>
>
>
|
|
|
>
>
>
|
<
>
>
|
>
>
>
>
>


<
<
|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
...
268
269
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294



295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314
315
316


317
318
319
320
321
322
323
324
** Allocate a NULL JSON object.
*/
static JsonNode *nullJson(void){
  JsonNode *pRes = xjd1JsonNew(0);
  if( pRes ) pRes->eJType = XJD1_NULL;
  return pRes;
}

/*
** If the JSON node passed as the first argument is of type XJD1_STRUCT,
** attempt to return a pointer to property zProperty.
**
** If zProperty is not defined, or if pStruct is not of type XJD1_STRUCT,
** return a pointer to a NULL value.
*/
static JsonNode *getProperty(JsonNode *pStruct, const char *zProperty){
  JsonStructElem *pElem;
  JsonNode *pRes = 0;

  if( pStruct && pStruct->eJType==XJD1_STRUCT ){
    for(pElem=pStruct->u.st.pFirst; pElem; pElem=pElem->pNext){
      if( strcmp(pElem->zLabel, zProperty)==0 ){
        pRes = xjd1JsonRef(pElem->pValue);
        break;
      }
    }
  }

  if( pRes==0 ){
    pRes = nullJson();
  }
  return pRes;
}

/*
** Evaluate an expression.  Return the result as a JSON object.
**
** The caller must free the returned JSON by a call xjdJsonFree().
*/
JsonNode *xjd1ExprEval(Expr *p){
................................................................................
  JsonNode *pJLeft, *pJRight;

  if( p==0 ) return nullJson();
  switch( p->eType ){
    case TK_JVALUE: {
      return xjd1JsonRef(p->u.json.p);
    }

    case TK_DOT: {
      JsonNode *pBase = xjd1ExprEval(p->u.lvalue.pLeft);

      pRes = getProperty(pBase, p->u.lvalue.zId);
      xjd1JsonFree(pBase);
      return pRes;
    }

    /* The x[y] operator. The result depends on the type of value x.
    **
    ** If x is of type XJD1_STRUCT, then expression y is converted to
    ** a string. The value returned is the value of property y of 
    ** object x.
    */
    case TK_LB: {
      pJLeft = xjd1ExprEval(p->u.bi.pLeft);
      pJRight = xjd1ExprEval(p->u.bi.pRight);

      switch( pJLeft->eJType ){
        case XJD1_STRUCT: {



          String idx;
          xjd1StringInit(&idx, 0, 0);
          xjd1JsonToString(pJRight, &idx);
          pRes = getProperty(pJLeft, idx.zBuf);
          xjd1StringClear(&idx);
          break;
        }

        case XJD1_ARRAY:
        case XJD1_STRING: {
          break;
        }


        default:
          pRes = nullJson();
          break;
      }

      xjd1JsonFree(pJLeft);
      xjd1JsonFree(pJRight);
      return pRes;
    }



    case TK_ID: {
      if( p->pQuery ){
        return xjd1QueryDoc(p->pQuery, p->u.id.zId);
      }else{
        return xjd1StmtDoc(p->pStmt, p->u.id.zId);
      }
    }

Changes to test/base02.test.

112
113
114
115
116
117
118







119

SELECT { x: "value" };
SELECT [1,4,9,16,25];
SELECT null;
SELECT true;
SELECT false;
.result 1.12 "hello world" null {"x":"value"} [1,4,9,16,25] null true false

















>
>
>
>
>
>
>

>
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
SELECT { x: "value" };
SELECT [1,4,9,16,25];
SELECT null;
SELECT true;
SELECT false;
.result 1.12 "hello world" null {"x":"value"} [1,4,9,16,25] null true false

.testcase 17
CREATE COLLECTION c2;
INSERT INTO c2 VALUE { a:1, b:2, c:"d", d:3 };
SELECT c2.a FROM c2;
SELECT c2["b"] FROM c2;
SELECT c2[c2.c] FROM c2;
.result 1 2 3