Add some more simple test cases for UPSERT. And a minor fix.
FossilOrigin-Name: 27cd3b2fb2ad0cf2b36741bd1057cb7973954d40456e9db158261a38b049d2b5
This commit is contained in:
parent
5015c9b50e
commit
2cc00423a0
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C New\stest\scases\sfor\supsert.
|
||||
D 2018-04-17T16:16:40.462
|
||||
C Add\ssome\smore\ssimple\stest\scases\sfor\sUPSERT.\sAnd\sa\sminor\sfix.
|
||||
D 2018-04-17T18:16:10.913
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439
|
||||
@ -452,7 +452,7 @@ F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 33f002c748fcb3be71d23641200c96b0c5c08e04d056f4fb874897ea9473e7e0
|
||||
F src/insert.c 6d9c6ab7ae76a038725e30385168686b9861e3eba9815e2c6d7c84698a419a7f
|
||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||
F src/loadext.c f6e4e416a736369f9e80eba609f0acda97148a8b0453784d670c78d3eed2f302
|
||||
F src/main.c 1648fc7a9bcfdbfd9a9a04af96ff2796c3164b3f3c7e56ed63a3c51cd11d198d
|
||||
@ -496,7 +496,7 @@ F src/shell.c.in cc960721e56ebc1a78773bb5d2f5608b54275f945cbe49e4afe919d6888062a
|
||||
F src/sqlite.h.in e0be726ea6e4e6571724d39d242472ecd8bd1ba6f84ade88e1641bde98a6d02b
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
|
||||
F src/sqliteInt.h 39ba44080f8cd5c6d46a6bf5b636d44cecbbd9b23a166c5dbf40d7b96c8c0763
|
||||
F src/sqliteInt.h 36471fded3bb07f247b8b6b1641f4793f10c72503508d2e1cdcb83c066164a1c
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@ -557,7 +557,7 @@ F src/tokenize.c 5b0c661a85f783d35b9883830736eeb63be4aefc4f6b7d9cd081d48782c041e
|
||||
F src/treeview.c 14d5d1254702ec96876aa52642cb31548612384134970409fae333b25b39d6bb
|
||||
F src/trigger.c fcb566b0df7bdefed4bff7e31aa7efa1c77cc0549e4ac79879d69490208ff966
|
||||
F src/update.c 5787acf0a12a20cf31c0c50db644a667590f720e404b3616bc2efeb9bd5bbc06
|
||||
F src/upsert.c 5d9491412105e06a69e98e51c88835eed74411192a0c1557cb8a986f9db7fb69
|
||||
F src/upsert.c e83fd8c0540873c4799e6aa7c433c65f0ae0d64e43f0fd9612f28f164de32823
|
||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||
F src/vacuum.c 762ee9bbf8733d87d8cd06f58d950e881982e416f8c767334a40ffd341b6bff5
|
||||
@ -1510,6 +1510,7 @@ F test/update2.test 5e67667e1c54017d964e626db765cf8bedcf87483c184f4c575bdb8c1dd2
|
||||
F test/upsert1.test 3b4e8e5932516115bfffb2269a44c416c5c26d0d57cc7dd16954d0b77fbc4cd9
|
||||
F test/upsert2.test 82ed5cbd4a13ff74240ece8ec97b6afd07446eac554ad5e93c12b42197844e0b
|
||||
F test/upsert3.test 46ee74a7d7ee797ca0ab79d44e78572d6778b7520e4ebb8f8c1553765b4eae2c
|
||||
F test/upsert4.test 490c82a37048b0258c94498ff3687b20cdbadfefe4d8a4e2d28f09e84f3b98a6
|
||||
F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568
|
||||
F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
|
||||
F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
|
||||
@ -1721,7 +1722,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 641f41722c68f1d51251b10d4d3d7c473d08ee999f6db20023ef6dcd4dc5f6e8
|
||||
R 1e259ef65026feaf02be85449e54247a
|
||||
U drh
|
||||
Z a453e1f58e770e0cd13a1e67daf6b8f7
|
||||
P 907b5a37c539ea67c285c87399b494c7fe15014389a2ea3d49e90640b58946ae
|
||||
R 9c3fbe02ac36c51a4bbb1c96ff0a3457
|
||||
U dan
|
||||
Z e4d8b74153527e8788840ae3c8608438
|
||||
|
@ -1 +1 @@
|
||||
907b5a37c539ea67c285c87399b494c7fe15014389a2ea3d49e90640b58946ae
|
||||
27cd3b2fb2ad0cf2b36741bd1057cb7973954d40456e9db158261a38b049d2b5
|
@ -1580,7 +1580,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UPSERT
|
||||
case OE_Update: {
|
||||
sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur, 0);
|
||||
sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur);
|
||||
/* Fall through */
|
||||
}
|
||||
#endif
|
||||
@ -1787,7 +1787,7 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UPSERT
|
||||
case OE_Update: {
|
||||
sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iDataCur, iIdxCur);
|
||||
sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix);
|
||||
/* Fall through */
|
||||
}
|
||||
#endif
|
||||
|
@ -4293,7 +4293,7 @@ const char *sqlite3JournalModename(int);
|
||||
void sqlite3UpsertDelete(sqlite3*,Upsert*);
|
||||
Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
|
||||
int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*);
|
||||
void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int,int);
|
||||
void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int);
|
||||
#else
|
||||
#define sqlite3UpsertNew(x,y,z,w) ((Upsert*)0)
|
||||
#define sqlite3UpsertDelete(x,y)
|
||||
|
15
src/upsert.c
15
src/upsert.c
@ -182,14 +182,19 @@ int sqlite3UpsertAnalyzeTarget(
|
||||
|
||||
/*
|
||||
** Generate bytecode that does an UPDATE as part of an upsert.
|
||||
**
|
||||
** If pIdx is NULL, then the UNIQUE constraint that failed was the IPK.
|
||||
** In this case parameter iCur is a cursor open on the table b-tree that
|
||||
** currently points to the conflicting table row. Otherwise, if pIdx
|
||||
** is not NULL, then pIdx is the constraint that failed and iCur is a
|
||||
** cursor points to the conflicting row.
|
||||
*/
|
||||
void sqlite3UpsertDoUpdate(
|
||||
Parse *pParse, /* The parsing and code-generating context */
|
||||
Upsert *pUpsert, /* The ON CONFLICT clause for the upsert */
|
||||
Table *pTab, /* The table being updated */
|
||||
Index *pIdx, /* The UNIQUE constraint that failed */
|
||||
int iDataCur, /* Cursor for the pTab, table being updated */
|
||||
int iIdxCur /* Cursor for pIdx */
|
||||
int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */
|
||||
){
|
||||
Vdbe *v = pParse->pVdbe;
|
||||
sqlite3 *db = pParse->db;
|
||||
@ -205,9 +210,9 @@ void sqlite3UpsertDoUpdate(
|
||||
/* We are dealing with an IPK */
|
||||
regKey = ++pParse->nMem;
|
||||
if( pIdx ){
|
||||
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regKey);
|
||||
sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regKey);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regKey);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regKey);
|
||||
}
|
||||
pE1 = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
|
||||
if( pE1 ){
|
||||
@ -231,7 +236,7 @@ void sqlite3UpsertDoUpdate(
|
||||
}
|
||||
for(i=0; i<pIdx->nKeyCol; i++){
|
||||
regKey = ++pParse->nMem;
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iDataCur, i, regKey);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regKey);
|
||||
j = pIdx->aiColumn[i];
|
||||
VdbeComment((v, "%s", pTab->aCol[j].zName));
|
||||
pE1 = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
|
||||
|
69
test/upsert4.test
Normal file
69
test/upsert4.test
Normal file
@ -0,0 +1,69 @@
|
||||
# 2018-04-17
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# Test cases for UPSERT
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix upsert2
|
||||
|
||||
foreach {tn sql} {
|
||||
1 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c UNIQUE) }
|
||||
2 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE) }
|
||||
3 { CREATE TABLE t1(a INT PRIMARY KEY, b, c UNIQUE) WITHOUT ROWID}
|
||||
} {
|
||||
reset_db
|
||||
execsql $sql
|
||||
|
||||
do_execsql_test 1.$tn.0 {
|
||||
INSERT INTO t1 VALUES(1, NULL, 'one');
|
||||
INSERT INTO t1 VALUES(2, NULL, 'two');
|
||||
INSERT INTO t1 VALUES(3, NULL, 'three');
|
||||
}
|
||||
|
||||
do_execsql_test 1.$tn.1 {
|
||||
INSERT INTO t1 VALUES(1, NULL, 'xyz') ON CONFLICT DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {
|
||||
1 {} one 2 {} two 3 {} three
|
||||
}
|
||||
|
||||
do_execsql_test 1.$tn.2 {
|
||||
INSERT INTO t1 VALUES(4, NULL, 'two') ON CONFLICT DO NOTHING;
|
||||
SELECT * FROM t1;
|
||||
} {
|
||||
1 {} one 2 {} two 3 {} three
|
||||
}
|
||||
|
||||
do_execsql_test 1.$tn.3 {
|
||||
INSERT INTO t1 VALUES(4, NULL, 'two') ON CONFLICT (c) DO UPDATE SET b = 1;
|
||||
SELECT * FROM t1;
|
||||
} {
|
||||
1 {} one 2 1 two 3 {} three
|
||||
}
|
||||
|
||||
do_execsql_test 1.$tn.4 {
|
||||
INSERT INTO t1 VALUES(2, NULL, 'zero') ON CONFLICT (a) DO UPDATE SET b=2;
|
||||
SELECT * FROM t1;
|
||||
} {1 {} one 2 2 two 3 {} three}
|
||||
|
||||
do_catchsql_test 1.$tn.5 {
|
||||
INSERT INTO t1 VALUES(2, NULL, 'zero') ON CONFLICT (a)
|
||||
DO UPDATE SET c = 'one';
|
||||
} {1 {UNIQUE constraint failed: t1.c}}
|
||||
|
||||
do_execsql_test 1.$tn.6 {
|
||||
SELECT * FROM t1;
|
||||
} {1 {} one 2 2 two 3 {} three}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user