diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 23 | ||||
-rw-r--r-- | src/parse.y | 13 | ||||
-rw-r--r-- | src/sqliteInt.h | 5 |
3 files changed, 23 insertions, 18 deletions
diff --git a/src/build.c b/src/build.c index 62d9bb012..2b3c8a1cf 100644 --- a/src/build.c +++ b/src/build.c @@ -4483,6 +4483,7 @@ void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ Upsert *pNext = p->pUpsertNext; sqlite3ExprListDelete(db, p->pUpsertTarget); sqlite3ExprListDelete(db, p->pUpsertSet); + sqlite3ExprDelete(db, p->pUpsertWhere); sqlite3DbFree(db, p); p = pNext; } @@ -4491,17 +4492,16 @@ void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ #ifndef SQLITE_OMIT_UPSERT /* -** Duplicate an Upsert object +** Duplicate an Upsert object. */ Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ - Upsert *pNew; if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); - if( pNew==0 ) return 0; - pNew->pUpsertTarget = sqlite3ExprListDup(db, p->pUpsertTarget, 0); - pNew->pUpsertSet = sqlite3ExprListDup(db, p->pUpsertSet, 0); - pNew->pUpsertNext = sqlite3UpsertDup(db, p->pUpsertNext); - return pNew; + return sqlite3UpsertNew(db, + sqlite3UpsertDup(db, p->pUpsertNext), + sqlite3ExprListDup(db, p->pUpsertTarget, 0), + sqlite3ExprListDup(db, p->pUpsertSet, 0), + sqlite3ExprDup(db, p->pUpsertWhere, 0) + ); } #endif /* SQLITE_OMIT_UPSERT */ @@ -4511,9 +4511,10 @@ Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ */ Upsert *sqlite3UpsertNew( sqlite3 *db, /* Determines which memory allocator to use */ - Upsert *pPrior, /* Append new upsert to the end of this one */ + Upsert *pPrior, /* Append this upsert to the end of the new one */ ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ - ExprList *pSet /* UPDATE columns, or NULL for a DO NOTHING */ + ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ + Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */ ){ Upsert *pNew; pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); @@ -4521,11 +4522,13 @@ Upsert *sqlite3UpsertNew( sqlite3UpsertDelete(db, pPrior); sqlite3ExprListDelete(db, pTarget); sqlite3ExprListDelete(db, pSet); + sqlite3ExprDelete(db, pWhere); return 0; }else{ pNew->pUpsertTarget = pTarget; pNew->pUpsertSet = pSet; pNew->pUpsertNext = pPrior; + pNew->pUpsertWhere = pWhere; } return pNew; } diff --git a/src/parse.y b/src/parse.y index 059cd2614..76643619e 100644 --- a/src/parse.y +++ b/src/parse.y @@ -870,14 +870,15 @@ cmd ::= with insert_cmd(R) INTO fullname(X) idlist_opt(F) DEFAULT VALUES. %type upsert {Upsert*} %destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} upsert(A) ::= . { A = 0; } -upsert(A) ::= upsert(X) ON CONFLICT LP sortlist(Y) RP DO UPDATE SET setlist(Z). - { A = sqlite3UpsertNew(pParse->db,X,Y,Z); /*X-overwrites-A*/ } -upsert(A) ::= upsert(X) ON DUPLIATE KEY UPDATE setlist(Z). - { A = sqlite3UpsertNew(pParse->db,X,0,Z); /*X-overwrites-A*/ } +upsert(A) ::= upsert(X) ON CONFLICT LP sortlist(Y) RP + DO UPDATE SET setlist(Z) where_opt(W). + { A = sqlite3UpsertNew(pParse->db,X,Y,Z,W); /*X-overwrites-A*/ } +upsert(A) ::= upsert(X) ON DUPLIATE KEY UPDATE setlist(Z) where_opt(W). + { A = sqlite3UpsertNew(pParse->db,X,0,Z,W); /*X-overwrites-A*/ } upsert(A) ::= upsert(X) ON CONFLICT LP sortlist(Y) RP DO NOTHING. - { A = sqlite3UpsertNew(pParse->db,X,Y,0); /*X-overwrites-A*/ } + { A = sqlite3UpsertNew(pParse->db,X,Y,0,0); /*X-overwrites-A*/ } upsert(A) ::= upsert(X) ON CONFLICT DO NOTHING. - { A = sqlite3UpsertNew(pParse->db,X,0,0); /*X-overwrites-A*/ } + { A = sqlite3UpsertNew(pParse->db,X,0,0,0); /*X-overwrites-A*/ } %type insert_cmd {int} insert_cmd(A) ::= INSERT orconf(R). {A = R;} diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1be52c258..bb23e25b4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2717,6 +2717,7 @@ struct NameContext { struct Upsert { ExprList *pUpsertTarget; /* Optional description of conflicting index */ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ + Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ Upsert *pUpsertNext; /* Next ON CONFLICT clause in the list */ }; @@ -4270,11 +4271,11 @@ const char *sqlite3JournalModename(int); #define sqlite3WithDelete(x,y) #endif #ifndef SQLITE_OMIT_UPSERT - Upsert *sqlite3UpsertNew(sqlite3*,Upsert*,ExprList*,ExprList*); + Upsert *sqlite3UpsertNew(sqlite3*,Upsert*,ExprList*,ExprList*,Expr*); void sqlite3UpsertDelete(sqlite3*,Upsert*); Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); #else -#define sqlite3UpsertNew(x,y,z) ((Upsert*)0) +#define sqlite3UpsertNew(x,y,z,w) ((Upsert*)0) #define sqlite3UpsertDelete(x,y) #define sqlite3UpsertDup(x,y) ((Upsert*)0) #endif |