UnQL

Check-in [14c401fdc2]
Login

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

Overview
Comment:Work towards subqueries.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 14c401fdc25c78805f923c49cccda18dfff9cd55
User & Date: drh 2011-07-02 23:19:06
Context
2011-07-08
19:19
Add tcl scripts to generate bubble diagrams for the query language syntax. check-in: 1afab97fd6 user: dan tags: trunk
2011-07-02
23:19
Work towards subqueries. check-in: 14c401fdc2 user: drh tags: trunk
2011-06-30
23:40
Tweak the Makefile so that it builds out-of-the-box on Linux and Mac. check-in: 6a68e48733 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

100
101
102
103
104
105
106

107
108
109
110
111
112
113
...
221
222
223
224
225
226
227



228

229
230
231
232
233
234
235
/*
** Callback for query expressions
*/
static int walkInitCallback(Expr *p, WalkAction *pAction){
  int rc = XJD1_OK;
  assert( p );
  p->pStmt = pAction->pStmt;

  if( p->eClass==XJD1_EXPR_Q ){
    rc = xjd1QueryInit(p->u.subq.p, pAction->pStmt, pAction->pQuery);
  }
  return rc;
}


................................................................................
      if( pRes==0 ) pRes = nullJson();
      return pRes;
    }
    case TK_LB: {
      return nullJson();   /* TBD */
    }
    case TK_ID: {



      return xjd1StmtDoc(p->pStmt, p->u.id.zId);

    }
  }
  pRes = xjd1JsonNew(0);
  if( pRes==0 ) return 0;
  pRes->eJType = XJD1_NULL;
  switch( p->eType ){
    case TK_STRUCT: {







>







 







>
>
>
|
>







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
** Callback for query expressions
*/
static int walkInitCallback(Expr *p, WalkAction *pAction){
  int rc = XJD1_OK;
  assert( p );
  p->pStmt = pAction->pStmt;
  p->pQuery = pAction->pQuery;
  if( p->eClass==XJD1_EXPR_Q ){
    rc = xjd1QueryInit(p->u.subq.p, pAction->pStmt, pAction->pQuery);
  }
  return rc;
}


................................................................................
      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);
      }
    }
  }
  pRes = xjd1JsonNew(0);
  if( pRes==0 ) return 0;
  pRes->eJType = XJD1_NULL;
  switch( p->eType ){
    case TK_STRUCT: {

Changes to src/query.c.

100
101
102
103
104
105
106



107
108
109
110
111
112
113
        pOut = xjd1DataSrcDoc(p->u.simple.pFrom, zDocName);
      }
    }else if( !p->u.compound.doneLeft ){
      pOut = xjd1QueryDoc(p->u.compound.pLeft, zDocName);
    }else{
      pOut = xjd1QueryDoc(p->u.compound.pRight, zDocName);
    }



  }
  return pOut;
}


/* Return true if there are no more rows available on this query */
int xjd1QueryEOF(Query *p){







>
>
>







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
        pOut = xjd1DataSrcDoc(p->u.simple.pFrom, zDocName);
      }
    }else if( !p->u.compound.doneLeft ){
      pOut = xjd1QueryDoc(p->u.compound.pLeft, zDocName);
    }else{
      pOut = xjd1QueryDoc(p->u.compound.pRight, zDocName);
    }
    if( pOut==0 && zDocName ){
      pOut = xjd1QueryDoc(p->pOuter, zDocName);
    }
  }
  return pOut;
}


/* Return true if there are no more rows available on this query */
int xjd1QueryEOF(Query *p){

Changes to src/update.c.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
  return pElem->pValue;  
}

/*
** The expression p is an L-value.  Find the corresponding JsonNode.
** Create it if necessary.
*/
static JsonNode *findOrCreateJsonNode(JsonNode **ppRoot, Expr *p){
  if( p==0 ) return 0;
  switch( p->eType ){
    case TK_DOT: {
      JsonNode *pBase = findOrCreateJsonNode(ppRoot, p->u.lvalue.pLeft);
      return findStructElement(pBase, p->u.lvalue.zId);
    }
    case TK_LB: {
      return 0;   /* TBD */
    }
    case TK_ID: {
      return *ppRoot;
    }
  }
  return 0;
}

/*
** Perform an edit on a JSON value.  Return the document after the change.
*/
static void reviseOneField(
  JsonNode **ppDoc,      /* The document to be edited */
  Expr *pLvalue,         /* Definition of field in document to be changed */
  Expr *pValue           /* New value for the field */
){
  JsonNode *pNode;
  JsonNode *pX;

  pNode = findOrCreateJsonNode(ppDoc, pLvalue);
  if( pNode ){
    pX = xjd1JsonEdit(xjd1ExprEval(pValue));
    xjd1JsonToNull(pNode);
    *pNode = *pX;
    free(pX);
  }
}
................................................................................

        pNewDoc  = xjd1JsonRef(pStmt->pDoc);
        pChng = pCmd->u.update.pChng;
        n = pChng->nEItem;
        for(i=0; i<n-1; i += 2){
          Expr *pLvalue = pChng->apEItem[i].pExpr;
          Expr *pExpr = pChng->apEItem[i+1].pExpr;
          reviseOneField(&pNewDoc, pLvalue, pExpr);
        }
        xjd1StringInit(&jsonNewDoc, 0, 0);
        xjd1JsonRender(&jsonNewDoc, pNewDoc);
        sqlite3_bind_int64(pReplace, 2, sqlite3_column_int64(pQuery, 0));
        sqlite3_bind_text(pReplace, 1, xjd1StringText(&jsonNewDoc), -1,
                          SQLITE_STATIC);
        sqlite3_step(pReplace);







|



|






|









|






|







 







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
  return pElem->pValue;  
}

/*
** The expression p is an L-value.  Find the corresponding JsonNode.
** Create it if necessary.
*/
static JsonNode *findOrCreateJsonNode(JsonNode *pRoot, Expr *p){
  if( p==0 ) return 0;
  switch( p->eType ){
    case TK_DOT: {
      JsonNode *pBase = findOrCreateJsonNode(pRoot, p->u.lvalue.pLeft);
      return findStructElement(pBase, p->u.lvalue.zId);
    }
    case TK_LB: {
      return 0;   /* TBD */
    }
    case TK_ID: {
      return pRoot;
    }
  }
  return 0;
}

/*
** Perform an edit on a JSON value.  Return the document after the change.
*/
static void reviseOneField(
  JsonNode *pDoc,        /* The document to be edited */
  Expr *pLvalue,         /* Definition of field in document to be changed */
  Expr *pValue           /* New value for the field */
){
  JsonNode *pNode;
  JsonNode *pX;

  pNode = findOrCreateJsonNode(pDoc, pLvalue);
  if( pNode ){
    pX = xjd1JsonEdit(xjd1ExprEval(pValue));
    xjd1JsonToNull(pNode);
    *pNode = *pX;
    free(pX);
  }
}
................................................................................

        pNewDoc  = xjd1JsonRef(pStmt->pDoc);
        pChng = pCmd->u.update.pChng;
        n = pChng->nEItem;
        for(i=0; i<n-1; i += 2){
          Expr *pLvalue = pChng->apEItem[i].pExpr;
          Expr *pExpr = pChng->apEItem[i+1].pExpr;
          reviseOneField(pNewDoc, pLvalue, pExpr);
        }
        xjd1StringInit(&jsonNewDoc, 0, 0);
        xjd1JsonRender(&jsonNewDoc, pNewDoc);
        sqlite3_bind_int64(pReplace, 2, sqlite3_column_int64(pQuery, 0));
        sqlite3_bind_text(pReplace, 1, xjd1StringText(&jsonNewDoc), -1,
                          SQLITE_STATIC);
        sqlite3_step(pReplace);

Changes to src/xjd1Int.h.

135
136
137
138
139
140
141

142
143
144
145
146
147
148
  ExprItem *apEItem;        /* The expression in the list */
};

/* A node of an expression */
struct Expr {
  u16 eType;                /* Expression node type */
  u16 eClass;               /* Expression class */

  xjd1_stmt *pStmt;         /* Statement this expression belongs to */
  union {
    struct {                /* Binary or unary operator. eClass==XJD1_EXPR_BI */
      Expr *pLeft;             /* Left operand.  Only operand for unary ops */
      Expr *pRight;            /* Right operand.  NULL for unary ops */
    } bi;
    struct {                /* Substructure nam.  eClass==EXPR_LVALUE */







>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  ExprItem *apEItem;        /* The expression in the list */
};

/* A node of an expression */
struct Expr {
  u16 eType;                /* Expression node type */
  u16 eClass;               /* Expression class */
  Query *pQuery;            /* Query this expression belongs to.  May be NULL */
  xjd1_stmt *pStmt;         /* Statement this expression belongs to */
  union {
    struct {                /* Binary or unary operator. eClass==XJD1_EXPR_BI */
      Expr *pLeft;             /* Left operand.  Only operand for unary ops */
      Expr *pRight;            /* Right operand.  NULL for unary ops */
    } bi;
    struct {                /* Substructure nam.  eClass==EXPR_LVALUE */