Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Basic UPDATE statements (and UPSERT) is now working. However, new fields are not added yet. |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
e2bc14a5be042ea6f112de98312ffdc6 |
User & Date: | drh 2011-06-30 20:44:41 |
Context
2011-06-30
| ||
22:24 | Update adds new fields as appropriate. check-in: 05d60ec33a user: drh tags: trunk | |
20:44 | Basic UPDATE statements (and UPSERT) is now working. However, new fields are not added yet. check-in: e2bc14a5be user: drh tags: trunk | |
20:13 | Incremental check-in. Various bug fixes. Progress toward getting UPDATE running. check-in: 0a23ab0e48 user: drh tags: trunk | |
Changes
Changes to src/expr.c.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
/*
** Initialize a list of expression in preparation for evaluation of a
** statement.
*/
int xjd1ExprListInit(ExprList *p, xjd1_stmt *pStmt, Query *pQuery){
WalkAction sAction;
memset(&sAction, 0, sizeof(sAction));
sAction.xQueryAction = walkInitCallback;
sAction.pStmt = pStmt;
sAction.pQuery = pQuery;
return walkExprList(p, &sAction);
}
/* Walker callback for ExprClose() */
|
| |
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
/*
** Initialize a list of expression in preparation for evaluation of a
** statement.
*/
int xjd1ExprListInit(ExprList *p, xjd1_stmt *pStmt, Query *pQuery){
WalkAction sAction;
memset(&sAction, 0, sizeof(sAction));
sAction.xNodeAction = walkInitCallback;
sAction.pStmt = pStmt;
sAction.pQuery = pQuery;
return walkExprList(p, &sAction);
}
/* Walker callback for ExprClose() */
|
Changes to src/json.c.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
** ************************************************************************* ** This file contains code used to parse and render JSON strings. */ #include "xjd1Int.h" #include <ctype.h> /* ** Reclaim memory used by JsonNode objects */ void xjd1JsonFree(JsonNode *p){ if( p && (--p->nRef)<=0 ){ switch( p->eJType ){ case XJD1_STRING: { free(p->u.z); break; } case XJD1_ARRAY: { int i; for(i=0; i<p->u.ar.nElem; i++){ xjd1JsonFree(p->u.ar.apElem[i]); } free(p->u.ar.apElem); break; } case XJD1_STRUCT: { JsonStructElem *pElem, *pNext; for(pElem=p->u.st.pFirst; pElem; pElem=pNext){ pNext = pElem->pNext; free(pElem->zLabel); xjd1JsonFree(pElem->pValue); free(pElem); } break; } } free(p); } } /* ** Allocate a new Json node. */ |
> < > | < > | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > |
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
** ************************************************************************* ** This file contains code used to parse and render JSON strings. */ #include "xjd1Int.h" #include <ctype.h> /* ** Change a JsonNode to be a NULL. Any substructure is deleted. */ void xjd1JsonToNull(JsonNode *p){ if( p==0 ) return; switch( p->eJType ){ case XJD1_STRING: { free(p->u.z); break; } case XJD1_ARRAY: { int i; for(i=0; i<p->u.ar.nElem; i++){ xjd1JsonFree(p->u.ar.apElem[i]); } free(p->u.ar.apElem); break; } case XJD1_STRUCT: { JsonStructElem *pElem, *pNext; for(pElem=p->u.st.pFirst; pElem; pElem=pNext){ pNext = pElem->pNext; free(pElem->zLabel); xjd1JsonFree(pElem->pValue); free(pElem); } break; } } p->eJType = XJD1_NULL; } /* ** Reclaim memory used by JsonNode objects */ void xjd1JsonFree(JsonNode *p){ if( p && (--p->nRef)<=0 ){ xjd1JsonToNull(p); free(p); } } /* ** Allocate a new Json node. */ |
Changes to src/update.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
** http://www.hwaci.com/drh/ ** ************************************************************************* ** Code to evaluate an UPDATE statement */ #include "xjd1Int.h" /* ** Perform an edit on a JSON value. Return the document after the change. */ static JsonNode *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 */ ){ return pDoc; } /* ** Evaluate an UPDATE. */ int xjd1UpdateStep(xjd1_stmt *pStmt){ ................................................................................ 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; pNewDoc = reviseOneField(pNewDoc, pLvalue, pExpr); } xjd1StringInit(&jsonNewDoc, 0, 0); xjd1JsonRender(&jsonNewDoc, pNewDoc); sqlite3_bind_int64(pReplace, 1, sqlite3_column_int64(pQuery, 0)); sqlite3_bind_text(pReplace, 2, xjd1StringText(&jsonNewDoc), -1, SQLITE_STATIC); sqlite3_step(pReplace); sqlite3_reset(pReplace); xjd1StringClear(&jsonNewDoc); xjd1JsonFree(pNewDoc); nUpdate++; } |
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
|
|
|
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
...
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
** http://www.hwaci.com/drh/ ** ************************************************************************* ** Code to evaluate an UPDATE statement */ #include "xjd1Int.h" /* ** 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); JsonStructElem *pElem; JsonNode *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 = pElem->pValue; break; } } } return pRes; } 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); } } /* ** Evaluate an UPDATE. */ int xjd1UpdateStep(xjd1_stmt *pStmt){ ................................................................................ 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); sqlite3_reset(pReplace); xjd1StringClear(&jsonNewDoc); xjd1JsonFree(pNewDoc); nUpdate++; } |
Changes to src/xjd1Int.h.
340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
void xjd1JsonRender(String*, const JsonNode*); int xjd1JsonToReal(const JsonNode*, double*); int xjd1JsonToString(const JsonNode*, String*); int xjd1JsonCompare(const JsonNode*, const JsonNode*); JsonNode *xjd1JsonNew(Pool*); JsonNode *xjd1JsonEdit(JsonNode*); void xjd1JsonFree(JsonNode*); void xjd1DequoteString(char*,int); /******************************** malloc.c ***********************************/ Pool *xjd1PoolNew(void); void xjd1PoolClear(Pool*); void xjd1PoolDelete(Pool*); void *xjd1PoolMalloc(Pool*, int); |
> |
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
void xjd1JsonRender(String*, const JsonNode*);
int xjd1JsonToReal(const JsonNode*, double*);
int xjd1JsonToString(const JsonNode*, String*);
int xjd1JsonCompare(const JsonNode*, const JsonNode*);
JsonNode *xjd1JsonNew(Pool*);
JsonNode *xjd1JsonEdit(JsonNode*);
void xjd1JsonFree(JsonNode*);
void xjd1JsonToNull(JsonNode*);
void xjd1DequoteString(char*,int);
/******************************** malloc.c ***********************************/
Pool *xjd1PoolNew(void);
void xjd1PoolClear(Pool*);
void xjd1PoolDelete(Pool*);
void *xjd1PoolMalloc(Pool*, int);
|
Changes to test/base01.test.
73 74 75 76 77 78 79 80 |
SELECT FROM counter;
.result {"name":"xyz","n":2}
.testcase 173
INSERT INTO counter VALUE {name:"pqr", n:0};
UPDATE counter SET counter.n=counter.n+1 WHERE counter.name=="xyz"
ELSE INSERT {name:"xyz", n:1};
SELECT FROM counter;
.result {"name":"xyz","n":2} {"name":"pqr","n":0}
|
| |
73 74 75 76 77 78 79 80 |
SELECT FROM counter;
.result {"name":"xyz","n":2}
.testcase 173
INSERT INTO counter VALUE {name:"pqr", n:0};
UPDATE counter SET counter.n=counter.n+1 WHERE counter.name=="xyz"
ELSE INSERT {name:"xyz", n:1};
SELECT FROM counter;
.result {"name":"xyz","n":3} {"name":"pqr","n":0}
|