mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Continue working to get UPDATE operational for WITHOUT ROWID tables.
Fix PRAGMA integrity_check so that it works on WITHOUT ROWID tables. FossilOrigin-Name: 0d4fea7462c0f61cd1c736cbcd7bea5ec2034d54
This commit is contained in:
27
manifest
27
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Make\ssure\sKeyInfo\sobjects\son\smulti-column\sindices\sof\sWITHOUT\sROWID\stables\nhave\sthe\scorrect\snField\sand\snXField\svalues.\s\sAlso,\sadd\sthe\nSQLITE_ENABLE_MODULE_COMMENT\scompile-time\soption\sand\sthe\sVdbeModuleComment()\nmacro\sand\suse\sit\sto\slabel\sentry\sand\sexit\spoints\sof\ssome\skey\sroutines.
|
C Continue\sworking\sto\sget\sUPDATE\soperational\sfor\sWITHOUT\sROWID\stables.\nFix\sPRAGMA\sintegrity_check\sso\sthat\sit\sworks\son\sWITHOUT\sROWID\stables.
|
||||||
D 2013-10-30T15:52:32.018
|
D 2013-10-30T20:22:55.102
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
|
F Makefile.in 0522b53cdc1fcfc18f3a98e0246add129136c654
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@@ -173,7 +173,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2
|
|||||||
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
||||||
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
|
F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
|
||||||
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
|
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
|
||||||
F src/delete.c d4917b7b977636f38b9c03040d8bb5f1457f9457
|
F src/delete.c 7b56fcc7e290f52e1825692cce37e2f001c7286b
|
||||||
F src/expr.c 3180b6332072b263f845592e72e92971af562ab0
|
F src/expr.c 3180b6332072b263f845592e72e92971af562ab0
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 628f81177299660a86e40359b3689b81f517e125
|
F src/fkey.c 628f81177299660a86e40359b3689b81f517e125
|
||||||
@@ -182,7 +182,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759
|
|||||||
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
|
||||||
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
|
||||||
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
|
||||||
F src/insert.c f8eea9f2303c90a4bfc62bb298dac45b7cc7cd11
|
F src/insert.c 4d832cca6d235ca0fc7f2c4acff23ca3246c8548
|
||||||
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
|
||||||
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
|
||||||
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
|
||||||
@@ -212,7 +212,7 @@ F src/parse.y 073a8294e1826f1b1656e84806b77e4199f4bb57
|
|||||||
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
|
||||||
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
|
||||||
F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
|
F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63
|
||||||
F src/pragma.c 21f9e61ca8a3ccf699d28d4a5ec04ef33824624a
|
F src/pragma.c c6612470d2db2cc30d226c1990faeaff7320a296
|
||||||
F src/prepare.c f47ba2bba7ac5650881ab6c41f6d33a6de1a8d52
|
F src/prepare.c f47ba2bba7ac5650881ab6c41f6d33a6de1a8d52
|
||||||
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
|
F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b
|
||||||
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
|
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
|
||||||
@@ -223,7 +223,7 @@ F src/shell.c d5eebdc6034014103de2b9d58e1d3f6f7de0fb50
|
|||||||
F src/sqlite.h.in 547a44dd4ff4d975e92a645ea2d609e543a83d0f
|
F src/sqlite.h.in 547a44dd4ff4d975e92a645ea2d609e543a83d0f
|
||||||
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
|
||||||
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
|
||||||
F src/sqliteInt.h 03e6459326d16123441ada0a053163fd1e2e341d
|
F src/sqliteInt.h f8fc23b598245de9460af2de163c91fc31d4fb27
|
||||||
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
|
||||||
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@@ -275,11 +275,11 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2
|
|||||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||||
F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2
|
F src/tokenize.c 70061085a51f2f4fc15ece94f32c03bcb78e63b2
|
||||||
F src/trigger.c 53d6b5d50b3b23d4fcd0a36504feb5cff9aed716
|
F src/trigger.c 53d6b5d50b3b23d4fcd0a36504feb5cff9aed716
|
||||||
F src/update.c e39378bc5ed0c42e80624229703e59b5c7a4d50a
|
F src/update.c 103ab76ccd4211b4c298ad4fe4c7a16fbd274818
|
||||||
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
|
||||||
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
|
F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918
|
||||||
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
|
||||||
F src/vdbe.c 3c98b77343f8a1f4624b86795bf29cfd008b0e4a
|
F src/vdbe.c 05857502186641716e8d9204de138b642208628f
|
||||||
F src/vdbe.h c18a2dd91c838601b867a214e43c5f66d5d001ba
|
F src/vdbe.h c18a2dd91c838601b867a214e43c5f66d5d001ba
|
||||||
F src/vdbeInt.h 42dcff74dbeb2b071e569b53f885fc9c2e4b4cb0
|
F src/vdbeInt.h 42dcff74dbeb2b071e569b53f885fc9c2e4b4cb0
|
||||||
F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
|
F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed
|
||||||
@@ -437,7 +437,7 @@ F test/e_expr.test d5cdda0e4ffb17760858ed4c7c4ece07efc40f71
|
|||||||
F test/e_fkey.test 17cfb40002d165299681f39aac0cb5890c359935
|
F test/e_fkey.test 17cfb40002d165299681f39aac0cb5890c359935
|
||||||
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
|
||||||
F test/e_insert.test 291e056e1a442a5e5166a989a8a03a46e38225ca
|
F test/e_insert.test 291e056e1a442a5e5166a989a8a03a46e38225ca
|
||||||
F test/e_reindex.test e175794fc41f8e8aef34772e87a7d7b7a9251dd3
|
F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
|
||||||
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
|
||||||
F test/e_select.test d3226cb94fae4af3f198e68e71f655e106d0be47
|
F test/e_select.test d3226cb94fae4af3f198e68e71f655e106d0be47
|
||||||
F test/e_select2.test 22c660a7becf0712c95e1ca1b2d9e716a1261460
|
F test/e_select2.test 22c660a7becf0712c95e1ca1b2d9e716a1261460
|
||||||
@@ -728,7 +728,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
|
|||||||
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
|
||||||
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
|
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
|
||||||
F test/permutations.test e154f5ed66d4d4913a99a110e870c9407f75b055
|
F test/permutations.test e154f5ed66d4d4913a99a110e870c9407f75b055
|
||||||
F test/pragma.test 5e7de6c32a5d764f09437d2025f07e4917b9e178
|
F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
|
||||||
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
|
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
|
||||||
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
|
||||||
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
|
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
|
||||||
@@ -1076,6 +1076,7 @@ F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
|
|||||||
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
|
||||||
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
|
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
|
||||||
F test/win32longpath.test e2aafc07e6990fe86c69be22a3d1a0e210cd329b
|
F test/win32longpath.test e2aafc07e6990fe86c69be22a3d1a0e210cd329b
|
||||||
|
F test/without_rowid1.test 1c3d5a5df986d931a3c5c19ffef5804bd324d9e5
|
||||||
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
|
||||||
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
|
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
|
||||||
F tool/build-all-msvc.bat 38623a30fd58288fda5cc7f7df2682aaab75c9d5 x
|
F tool/build-all-msvc.bat 38623a30fd58288fda5cc7f7df2682aaab75c9d5 x
|
||||||
@@ -1127,7 +1128,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
|
||||||
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
|
||||||
P 72d45eb79b5d0505050cff57a00d725948b2a0c0
|
P 6d9af6065fc0da8337aee2297a8da7511eecccf1
|
||||||
R 52fcbe874e2522b4dc7ef0c1b4c145a0
|
R 00013e769d264c62972e72b68f63eb56
|
||||||
U drh
|
U drh
|
||||||
Z 3d4390b53d26d2b8ae9a915e21b79a8b
|
Z 05e092e5dbaf4f4f4e2497c5914c1170
|
||||||
|
@@ -1 +1 @@
|
|||||||
6d9af6065fc0da8337aee2297a8da7511eecccf1
|
0d4fea7462c0f61cd1c736cbcd7bea5ec2034d54
|
@@ -604,8 +604,11 @@ void sqlite3GenerateRowDelete(
|
|||||||
** a view (in which case the only effect of the DELETE statement is to
|
** a view (in which case the only effect of the DELETE statement is to
|
||||||
** fire the INSTEAD OF triggers). */
|
** fire the INSTEAD OF triggers). */
|
||||||
if( pTab->pSelect==0 ){
|
if( pTab->pSelect==0 ){
|
||||||
sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
|
Index *pPk;
|
||||||
sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
|
int iMainCur;
|
||||||
|
sqlite3PrincipleBtree(pTab, iCur, &pPk, &iMainCur);
|
||||||
|
sqlite3GenerateRowIndexDelete(pParse, pTab, iMainCur, 0);
|
||||||
|
sqlite3VdbeAddOp2(v, OP_Delete, iMainCur, (count?OPFLAG_NCHANGE:0));
|
||||||
if( count ){
|
if( count ){
|
||||||
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
|
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
|
||||||
}
|
}
|
||||||
|
96
src/insert.c
96
src/insert.c
@@ -1159,6 +1159,40 @@ static int sqlite3PrimaryKeyRegisters(Parse *pParse, Index *pPk, int regFirst){
|
|||||||
return regPk;
|
return regPk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Locate the "principle btree" for a table. This is the table itself for
|
||||||
|
** ordinary tables, but for WITHOUT ROWID tables, the principle btree is the
|
||||||
|
** PRIMARY KEY index.
|
||||||
|
**
|
||||||
|
** Inputs are pTab and baseCur. The *ppPk is written with a pointer to the
|
||||||
|
** PRIMARY KEY index for WITHOUT ROWID tables or with NULL for ordinary
|
||||||
|
** tables. The *piPkCur is written with the cursor to use, assuming that the
|
||||||
|
** table cursor is baseCur and that index cursors are consecutively numbered
|
||||||
|
** thereafter.
|
||||||
|
*/
|
||||||
|
void sqlite3PrincipleBtree(
|
||||||
|
Table *pTab, /* The main Table object */
|
||||||
|
int baseCur, /* VDBE cursor for main table. */
|
||||||
|
Index **ppPk, /* Write PRIMARY KEY index of WITHOUT ROWID tables here */
|
||||||
|
int *piPkCur /* Either baseCur or the cursor for *ppPk */
|
||||||
|
){
|
||||||
|
int pkCur;
|
||||||
|
Index *pPk;
|
||||||
|
if( !HasRowid(pTab) ){
|
||||||
|
pkCur = baseCur+1;
|
||||||
|
pPk = pTab->pIndex;
|
||||||
|
while( ALWAYS(pPk) && pPk->autoIndex!=2 ){
|
||||||
|
pPk=pPk->pNext;
|
||||||
|
pkCur++;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pkCur = baseCur;
|
||||||
|
pPk = 0;
|
||||||
|
}
|
||||||
|
*ppPk = pPk;
|
||||||
|
*piPkCur = pkCur;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Generate code to do constraint checks prior to an INSERT or an UPDATE.
|
** Generate code to do constraint checks prior to an INSERT or an UPDATE.
|
||||||
@@ -1263,6 +1297,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
int regOldPk; /* Previous rowid or PRIMARY KEY value */
|
int regOldPk; /* Previous rowid or PRIMARY KEY value */
|
||||||
int regNewPk = 0; /* New PRIMARY KEY value */
|
int regNewPk = 0; /* New PRIMARY KEY value */
|
||||||
int pkCur = 0; /* Cursor used by the PRIMARY KEY */
|
int pkCur = 0; /* Cursor used by the PRIMARY KEY */
|
||||||
|
int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
|
||||||
|
|
||||||
regOldPk = (pkChng && isUpdate) ? pkChng : regRowid;
|
regOldPk = (pkChng && isUpdate) ? pkChng : regRowid;
|
||||||
db = pParse->db;
|
db = pParse->db;
|
||||||
@@ -1271,20 +1306,15 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
|
||||||
nCol = pTab->nCol;
|
nCol = pTab->nCol;
|
||||||
regData = regRowid + 1;
|
regData = regRowid + 1;
|
||||||
VdbeModuleComment((v, "BEGIN: GenerateConstraintChecks(%d,%d,%d)",
|
|
||||||
baseCur, regRowid, pkChng));
|
|
||||||
|
|
||||||
/* For WITHOUT ROWID tables, we'll need to know the Index and the cursor
|
/* For WITHOUT ROWID tables, we'll need to know the Index and the cursor
|
||||||
** number for the PRIMARY KEY index */
|
** number for the PRIMARY KEY index */
|
||||||
if( !HasRowid(pTab) ){
|
sqlite3PrincipleBtree(pTab, baseCur, &pPk, &pkCur);
|
||||||
assert( pkChng==0 || isUpdate!=0 );
|
nPkField = pPk ? pPk->nKeyCol : 1;
|
||||||
pkCur = baseCur+1;
|
|
||||||
pPk = pTab->pIndex;
|
/* Record that this module has started */
|
||||||
while( ALWAYS(pPk) && pPk->autoIndex!=2 ){
|
VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
|
||||||
pPk=pPk->pNext;
|
baseCur, regRowid, pkChng, regOldPk, pkCur));
|
||||||
pkCur++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test all NOT NULL constraints.
|
/* Test all NOT NULL constraints.
|
||||||
*/
|
*/
|
||||||
@@ -1366,7 +1396,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
**
|
**
|
||||||
** This block only runs for tables that have a rowid.
|
** This block only runs for tables that have a rowid.
|
||||||
*/
|
*/
|
||||||
if( pkChng && pkCur==0 ){
|
if( pkChng && pPk==0 ){
|
||||||
int addrRowidOk = sqlite3VdbeMakeLabel(v);
|
int addrRowidOk = sqlite3VdbeMakeLabel(v);
|
||||||
|
|
||||||
onError = pTab->keyConf;
|
onError = pTab->keyConf;
|
||||||
@@ -1492,7 +1522,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if the new index entry will be unique */
|
/* Check to see if the new index entry will be unique */
|
||||||
regR = sqlite3GetTempReg(pParse);
|
regR = sqlite3GetTempRange(pParse, nPkField);
|
||||||
sqlite3VdbeAddOp4Int(v, OP_NoConflict, idxCur, addrUniqueOk,
|
sqlite3VdbeAddOp4Int(v, OP_NoConflict, idxCur, addrUniqueOk,
|
||||||
regIdx, pIdx->nKeyCol);
|
regIdx, pIdx->nKeyCol);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -1510,13 +1540,15 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
** if the PRIMARY KEY has changed. If the PRIMARY KEY is unchanged,
|
** if the PRIMARY KEY has changed. If the PRIMARY KEY is unchanged,
|
||||||
** then the matching entry is just the original row that is being
|
** then the matching entry is just the original row that is being
|
||||||
** modified. */
|
** modified. */
|
||||||
int addrPkConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
|
if( onError!=OE_Replace ){
|
||||||
for(i=0; i<pPk->nKeyCol-1; i++){
|
int addrPkConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
|
||||||
sqlite3VdbeAddOp3(v, OP_Ne,
|
for(i=0; i<pPk->nKeyCol-1; i++){
|
||||||
regOldPk+pPk->aiColumn[i], addrPkConflict, regIdx+i);
|
sqlite3VdbeAddOp3(v, OP_Ne, regOldPk+pPk->aiColumn[i]+1,
|
||||||
|
addrPkConflict, regIdx+i);
|
||||||
|
}
|
||||||
|
sqlite3VdbeAddOp3(v, OP_Eq, regOldPk+pPk->aiColumn[i]+1,
|
||||||
|
addrUniqueOk, regIdx+i);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq,
|
|
||||||
regOldPk+pPk->aiColumn[i], addrUniqueOk, regIdx+i);
|
|
||||||
}else{
|
}else{
|
||||||
/* For a UNIQUE index on a WITHOUT ROWID table, conflict only if the
|
/* For a UNIQUE index on a WITHOUT ROWID table, conflict only if the
|
||||||
** PRIMARY KEY value of the match is different from the old PRIMARY KEY
|
** PRIMARY KEY value of the match is different from the old PRIMARY KEY
|
||||||
@@ -1524,13 +1556,13 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
int addrConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol*2;
|
int addrConflict = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol*2;
|
||||||
assert( pIdx->nKeyCol + pPk->nKeyCol == pIdx->nColumn );
|
assert( pIdx->nKeyCol + pPk->nKeyCol == pIdx->nColumn );
|
||||||
for(i=0; i<pPk->nKeyCol-1; i++){
|
for(i=0; i<pPk->nKeyCol-1; i++){
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, idxCur, pIdx->nKeyCol+i, regR);
|
sqlite3VdbeAddOp3(v, OP_Column, idxCur, pIdx->nKeyCol+i, regR+i);
|
||||||
sqlite3VdbeAddOp3(v, OP_Ne,
|
sqlite3VdbeAddOp3(v, OP_Ne,
|
||||||
regOldPk+pPk->aiColumn[i], addrConflict, regR);
|
regOldPk+pPk->aiColumn[i], addrConflict, regR+i);
|
||||||
}
|
}
|
||||||
sqlite3VdbeAddOp3(v, OP_Column, idxCur, pIdx->nKeyCol+i, regR);
|
sqlite3VdbeAddOp3(v, OP_Column, idxCur, pIdx->nKeyCol+i, regR+i);
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq,
|
sqlite3VdbeAddOp3(v, OP_Eq,
|
||||||
regOldPk+pPk->aiColumn[i], addrUniqueOk, regR);
|
regOldPk+pPk->aiColumn[i], addrUniqueOk, regR+i);
|
||||||
}
|
}
|
||||||
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
|
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
|
||||||
|
|
||||||
@@ -1575,9 +1607,13 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
if( db->flags&SQLITE_RecTriggers ){
|
if( db->flags&SQLITE_RecTriggers ){
|
||||||
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
|
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
|
||||||
}
|
}
|
||||||
sqlite3GenerateRowDelete(
|
if( pIdx==pPk ){
|
||||||
pParse, pTab, pTrigger, baseCur, regR, 0, 0, OE_Replace
|
/*sqlite3VdbeAddOp3(v, OP_IdxDelete, pkCur, regIdx, pIdx->nColumn);*/
|
||||||
);
|
sqlite3VdbeAddOp1(v, OP_Delete, pkCur);
|
||||||
|
}else{
|
||||||
|
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, baseCur,
|
||||||
|
regR, nPkField, 0, OE_Replace);
|
||||||
|
}
|
||||||
seenReplace = 1;
|
seenReplace = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1589,7 +1625,7 @@ void sqlite3GenerateConstraintChecks(
|
|||||||
if( pbMayReplace ){
|
if( pbMayReplace ){
|
||||||
*pbMayReplace = seenReplace;
|
*pbMayReplace = seenReplace;
|
||||||
}
|
}
|
||||||
VdbeModuleComment((v, "END: GenerateConstraintChecks()"));
|
VdbeModuleComment((v, "END: GenCnstCks()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1679,7 +1715,11 @@ int sqlite3OpenTableAndIndices(
|
|||||||
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
|
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
|
||||||
v = sqlite3GetVdbe(pParse);
|
v = sqlite3GetVdbe(pParse);
|
||||||
assert( v!=0 );
|
assert( v!=0 );
|
||||||
sqlite3OpenTable(pParse, baseCur, iDb, pTab, op);
|
if( pkCur<0 ){
|
||||||
|
sqlite3OpenTable(pParse, baseCur, iDb, pTab, op);
|
||||||
|
}else{
|
||||||
|
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
|
||||||
|
}
|
||||||
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||||
int iCur = (pkCur>=0 && pIdx->autoIndex==2) ? pkCur : i+baseCur;
|
int iCur = (pkCur>=0 && pIdx->autoIndex==2) ? pkCur : i+baseCur;
|
||||||
|
61
src/pragma.c
61
src/pragma.c
@@ -1846,8 +1846,10 @@ void sqlite3Pragma(
|
|||||||
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
|
||||||
Table *pTab = sqliteHashData(x);
|
Table *pTab = sqliteHashData(x);
|
||||||
Index *pIdx;
|
Index *pIdx;
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
|
if( HasRowid(pTab) ){
|
||||||
cnt++;
|
sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
|
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
|
||||||
cnt++;
|
cnt++;
|
||||||
@@ -1855,7 +1857,7 @@ void sqlite3Pragma(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure sufficient number of registers have been allocated */
|
/* Make sure sufficient number of registers have been allocated */
|
||||||
pParse->nMem = MAX( pParse->nMem, cnt+7 );
|
pParse->nMem = MAX( pParse->nMem, cnt+8 );
|
||||||
|
|
||||||
/* Do the b-tree integrity checks */
|
/* Do the b-tree integrity checks */
|
||||||
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
|
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
|
||||||
@@ -1873,44 +1875,44 @@ void sqlite3Pragma(
|
|||||||
*/
|
*/
|
||||||
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
|
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
|
||||||
Table *pTab = sqliteHashData(x);
|
Table *pTab = sqliteHashData(x);
|
||||||
Index *pIdx;
|
Index *pIdx, *pPk;
|
||||||
int loopTop;
|
int loopTop;
|
||||||
|
int pkCur;
|
||||||
|
|
||||||
if( pTab->pIndex==0 ) continue;
|
if( pTab->pIndex==0 ) continue;
|
||||||
|
sqlite3PrincipleBtree(pTab, 1, &pPk, &pkCur);
|
||||||
|
pkCur = (pPk==0) ? -1 : 1;
|
||||||
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
|
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeJumpHere(v, addr);
|
sqlite3VdbeJumpHere(v, addr);
|
||||||
sqlite3ExprCacheClear(pParse);
|
sqlite3ExprCacheClear(pParse);
|
||||||
sqlite3OpenTableAndIndices(pParse, pTab, 1, -1, OP_OpenRead);
|
sqlite3OpenTableAndIndices(pParse, pTab, 1, pkCur, OP_OpenRead);
|
||||||
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
|
||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
|
sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
|
||||||
}
|
}
|
||||||
pParse->nMem = MAX(pParse->nMem, 7+j);
|
pParse->nMem = MAX(pParse->nMem, 8+j);
|
||||||
loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1;
|
sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
|
||||||
|
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
|
||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
int jmp2, jmp3;
|
int jmp2, jmp3, jmp4;
|
||||||
int r1;
|
int r1;
|
||||||
static const VdbeOpList idxErr[] = {
|
if( pPk==pIdx ) continue;
|
||||||
{ OP_AddImm, 1, -1, 0},
|
|
||||||
{ OP_String8, 0, 3, 0}, /* 1 */
|
|
||||||
{ OP_Rowid, 1, 4, 0},
|
|
||||||
{ OP_String8, 0, 5, 0}, /* 3 */
|
|
||||||
{ OP_String8, 0, 6, 0}, /* 4 */
|
|
||||||
{ OP_Concat, 4, 3, 3},
|
|
||||||
{ OP_Concat, 5, 3, 3},
|
|
||||||
{ OP_Concat, 6, 3, 3},
|
|
||||||
{ OP_ResultRow, 3, 1, 0},
|
|
||||||
{ OP_IfPos, 1, 0, 0}, /* 9 */
|
|
||||||
{ OP_Halt, 0, 0, 0},
|
|
||||||
};
|
|
||||||
r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 0, 0, &jmp3);
|
r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 0, 0, &jmp3);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1); /* increment entry count */
|
sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
|
||||||
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nKeyCol+1);
|
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nKeyCol+1);
|
||||||
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
|
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
|
||||||
sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
|
||||||
sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
|
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
|
||||||
sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, " missing from index ",
|
||||||
sqlite3VdbeJumpHere(v, addr+9);
|
P4_STATIC);
|
||||||
|
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||||
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
|
||||||
|
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
|
||||||
|
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
|
||||||
|
jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
|
||||||
|
sqlite3VdbeAddOp0(v, OP_Halt);
|
||||||
|
sqlite3VdbeJumpHere(v, jmp4);
|
||||||
sqlite3VdbeJumpHere(v, jmp2);
|
sqlite3VdbeJumpHere(v, jmp2);
|
||||||
sqlite3VdbeResolveLabel(v, jmp3);
|
sqlite3VdbeResolveLabel(v, jmp3);
|
||||||
}
|
}
|
||||||
@@ -1920,11 +1922,12 @@ void sqlite3Pragma(
|
|||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
|
||||||
"wrong # of entries in index ", P4_STATIC);
|
"wrong # of entries in index ", P4_STATIC);
|
||||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||||
|
if( pPk==pIdx ) continue;
|
||||||
addr = sqlite3VdbeCurrentAddr(v);
|
addr = sqlite3VdbeCurrentAddr(v);
|
||||||
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
|
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
|
||||||
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
|
||||||
sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
|
sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
|
||||||
sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3);
|
sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3);
|
||||||
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
|
||||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
|
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
|
||||||
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
|
||||||
|
@@ -1526,7 +1526,7 @@ struct KeyInfo {
|
|||||||
sqlite3 *db; /* The database connection */
|
sqlite3 *db; /* The database connection */
|
||||||
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
|
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
|
||||||
u16 nField; /* Number of key columns in the index */
|
u16 nField; /* Number of key columns in the index */
|
||||||
u16 nXField; /* Number of columns beyond the key columns */
|
u16 nXField; /* Number of columns beyond the key columns */
|
||||||
u8 *aSortOrder; /* Sort order for each column. */
|
u8 *aSortOrder; /* Sort order for each column. */
|
||||||
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
|
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
|
||||||
};
|
};
|
||||||
@@ -2922,6 +2922,7 @@ int sqlite3IsRowid(const char*);
|
|||||||
void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,i16,u8,u8);
|
void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,i16,u8,u8);
|
||||||
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
|
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
|
||||||
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
|
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
|
||||||
|
void sqlite3PrincipleBtree(Table*,int,Index**,int*);
|
||||||
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
|
void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
|
||||||
int*,int,int,int,int,int*);
|
int*,int,int,int,int,int*);
|
||||||
void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
|
void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
|
||||||
|
14
src/update.c
14
src/update.c
@@ -102,6 +102,7 @@ void sqlite3Update(
|
|||||||
Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
|
Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
|
||||||
int nIdx; /* Number of indices that need updating */
|
int nIdx; /* Number of indices that need updating */
|
||||||
int iCur; /* VDBE Cursor number of pTab */
|
int iCur; /* VDBE Cursor number of pTab */
|
||||||
|
int pkCur; /* VDBE Cursor for the pPk index */
|
||||||
sqlite3 *db; /* The database structure */
|
sqlite3 *db; /* The database structure */
|
||||||
int *aRegIdx = 0; /* One register assigned to each index to be updated */
|
int *aRegIdx = 0; /* One register assigned to each index to be updated */
|
||||||
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
|
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
|
||||||
@@ -185,7 +186,10 @@ void sqlite3Update(
|
|||||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||||
pParse->nTab++;
|
pParse->nTab++;
|
||||||
}
|
}
|
||||||
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
|
|
||||||
|
/* For WITHOUT ROWID tables, we'll need to know the Index and the cursor
|
||||||
|
** number for the PRIMARY KEY index */
|
||||||
|
sqlite3PrincipleBtree(pTab, iCur, &pPk, &pkCur);
|
||||||
|
|
||||||
/* Initialize the name-context */
|
/* Initialize the name-context */
|
||||||
memset(&sNC, 0, sizeof(sNC));
|
memset(&sNC, 0, sizeof(sNC));
|
||||||
@@ -531,8 +535,12 @@ void sqlite3Update(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the index entries associated with the current record. */
|
/* Delete the index entries associated with the current record. */
|
||||||
j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
|
if( pPk ){
|
||||||
sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
|
/*j1 = sqlite3VdbeAddOp3(v, OP_NotFound, pkCur, */
|
||||||
|
}else{
|
||||||
|
j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
|
||||||
|
sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
|
||||||
|
}
|
||||||
|
|
||||||
/* If changing the record number, delete the old record. */
|
/* If changing the record number, delete the old record. */
|
||||||
if( hasFK || chngRowid ){
|
if( hasFK || chngRowid ){
|
||||||
|
@@ -3734,7 +3734,13 @@ case OP_Found: { /* jump, in3 */
|
|||||||
r.nField = (u16)pOp->p4.i;
|
r.nField = (u16)pOp->p4.i;
|
||||||
r.aMem = pIn3;
|
r.aMem = pIn3;
|
||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
{ int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
|
{
|
||||||
|
int i;
|
||||||
|
for(i=0; i<r.nField; i++){
|
||||||
|
assert( memIsValid(&r.aMem[i]) );
|
||||||
|
if( i ) REGISTER_TRACE(pOp->p3+i, &r.aMem[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
r.flags = UNPACKED_PREFIX_MATCH;
|
r.flags = UNPACKED_PREFIX_MATCH;
|
||||||
pIdxKey = &r;
|
pIdxKey = &r;
|
||||||
|
@@ -67,10 +67,10 @@ sqlite3 db test.db
|
|||||||
do_execsql_test e_reindex-1.3 {
|
do_execsql_test e_reindex-1.3 {
|
||||||
PRAGMA integrity_check;
|
PRAGMA integrity_check;
|
||||||
} [list \
|
} [list \
|
||||||
{rowid 4 missing from index i2} \
|
{row 3 missing from index i2} \
|
||||||
{rowid 4 missing from index i1} \
|
{row 3 missing from index i1} \
|
||||||
{rowid 5 missing from index i2} \
|
{row 4 missing from index i2} \
|
||||||
{rowid 5 missing from index i1} \
|
{row 4 missing from index i1} \
|
||||||
{wrong # of entries in index i2} \
|
{wrong # of entries in index i2} \
|
||||||
{wrong # of entries in index i1}
|
{wrong # of entries in index i1}
|
||||||
]
|
]
|
||||||
|
@@ -285,31 +285,31 @@ ifcapable attach {
|
|||||||
db close
|
db close
|
||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
execsql {PRAGMA integrity_check}
|
execsql {PRAGMA integrity_check}
|
||||||
} {{rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}}
|
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
do_test pragma-3.3 {
|
do_test pragma-3.3 {
|
||||||
execsql {PRAGMA integrity_check=1}
|
execsql {PRAGMA integrity_check=1}
|
||||||
} {{rowid 1 missing from index i2}}
|
} {{row 1 missing from index i2}}
|
||||||
do_test pragma-3.4 {
|
do_test pragma-3.4 {
|
||||||
execsql {
|
execsql {
|
||||||
ATTACH DATABASE 'test.db' AS t2;
|
ATTACH DATABASE 'test.db' AS t2;
|
||||||
PRAGMA integrity_check
|
PRAGMA integrity_check
|
||||||
}
|
}
|
||||||
} {{rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}}
|
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
do_test pragma-3.5 {
|
do_test pragma-3.5 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=4
|
PRAGMA integrity_check=4
|
||||||
}
|
}
|
||||||
} {{rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2} {rowid 1 missing from index i2}}
|
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2}}
|
||||||
do_test pragma-3.6 {
|
do_test pragma-3.6 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=xyz
|
PRAGMA integrity_check=xyz
|
||||||
}
|
}
|
||||||
} {{rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}}
|
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
do_test pragma-3.7 {
|
do_test pragma-3.7 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=0
|
PRAGMA integrity_check=0
|
||||||
}
|
}
|
||||||
} {{rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}}
|
} {{row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
|
|
||||||
# Add additional corruption by appending unused pages to the end of
|
# Add additional corruption by appending unused pages to the end of
|
||||||
# the database file testerr.db
|
# the database file testerr.db
|
||||||
@@ -344,7 +344,7 @@ ifcapable attach {
|
|||||||
} {{*** in database t2 ***
|
} {{*** in database t2 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}}
|
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
do_test pragma-3.10 {
|
do_test pragma-3.10 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=1
|
PRAGMA integrity_check=1
|
||||||
@@ -358,7 +358,7 @@ Page 4 is never used}}
|
|||||||
} {{*** in database t2 ***
|
} {{*** in database t2 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from index i2}}
|
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2}}
|
||||||
do_test pragma-3.12 {
|
do_test pragma-3.12 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=4
|
PRAGMA integrity_check=4
|
||||||
@@ -366,7 +366,7 @@ Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from inde
|
|||||||
} {{*** in database t2 ***
|
} {{*** in database t2 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2}}
|
Page 6 is never used} {row 1 missing from index i2}}
|
||||||
do_test pragma-3.13 {
|
do_test pragma-3.13 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=3
|
PRAGMA integrity_check=3
|
||||||
@@ -390,10 +390,10 @@ Page 5 is never used}}
|
|||||||
} {{*** in database t2 ***
|
} {{*** in database t2 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 ***
|
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}}
|
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2}}
|
||||||
do_test pragma-3.16 {
|
do_test pragma-3.16 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check(10)
|
PRAGMA integrity_check(10)
|
||||||
@@ -401,10 +401,10 @@ Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from inde
|
|||||||
} {{*** in database t2 ***
|
} {{*** in database t2 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 ***
|
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2}}
|
Page 6 is never used} {row 1 missing from index i2}}
|
||||||
do_test pragma-3.17 {
|
do_test pragma-3.17 {
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA integrity_check=8
|
PRAGMA integrity_check=8
|
||||||
@@ -412,7 +412,7 @@ Page 6 is never used} {rowid 1 missing from index i2}}
|
|||||||
} {{*** in database t2 ***
|
} {{*** in database t2 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 ***
|
Page 6 is never used} {row 1 missing from index i2} {row 2 missing from index i2} {wrong # of entries in index i2} {*** in database t3 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used}}
|
Page 5 is never used}}
|
||||||
do_test pragma-3.18 {
|
do_test pragma-3.18 {
|
||||||
@@ -422,7 +422,7 @@ Page 5 is never used}}
|
|||||||
} {{*** in database t2 ***
|
} {{*** in database t2 ***
|
||||||
Page 4 is never used
|
Page 4 is never used
|
||||||
Page 5 is never used
|
Page 5 is never used
|
||||||
Page 6 is never used} {rowid 1 missing from index i2}}
|
Page 6 is never used} {row 1 missing from index i2}}
|
||||||
}
|
}
|
||||||
do_test pragma-3.19 {
|
do_test pragma-3.19 {
|
||||||
catch {db close}
|
catch {db close}
|
||||||
|
66
test/without_rowid1.test
Normal file
66
test/without_rowid1.test
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# 2013-10-30
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# This file implements regression tests for SQLite library. The
|
||||||
|
# focus of this file is testing WITHOUT ROWID tables.
|
||||||
|
#
|
||||||
|
|
||||||
|
set testdir [file dirname $argv0]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
# Create and query a WITHOUT ROWID table.
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid1-1.0 {
|
||||||
|
CREATE TABLE t1(a,b,c,d, PRIMARY KEY(c,a)) WITHOUT ROWID;
|
||||||
|
CREATE INDEX t1bd ON t1(b, d);
|
||||||
|
INSERT INTO t1 VALUES('journal','sherman','ammonia','helena');
|
||||||
|
INSERT INTO t1 VALUES('dynamic','juliet','flipper','command');
|
||||||
|
INSERT INTO t1 VALUES('journal','sherman','gamma','patriot');
|
||||||
|
INSERT INTO t1 VALUES('arctic','sleep','ammonia','helena');
|
||||||
|
SELECT *, '|' FROM t1 ORDER BY c, a;
|
||||||
|
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}
|
||||||
|
|
||||||
|
integrity_check without_rowid1-1.0ic
|
||||||
|
|
||||||
|
do_execsql_test without_rowid1-1.1 {
|
||||||
|
SELECT *, '|' FROM t1 ORDER BY +c, a;
|
||||||
|
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}
|
||||||
|
|
||||||
|
do_execsql_test without_rowid1-1.2 {
|
||||||
|
SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC;
|
||||||
|
} {journal sherman gamma patriot | dynamic juliet flipper command | journal sherman ammonia helena | arctic sleep ammonia helena |}
|
||||||
|
|
||||||
|
do_execsql_test without_rowid1-1.11 {
|
||||||
|
SELECT *, '|' FROM t1 ORDER BY b, d;
|
||||||
|
} {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |}
|
||||||
|
|
||||||
|
do_execsql_test without_rowid1-1.12 {
|
||||||
|
SELECT *, '|' FROM t1 ORDER BY +b, d;
|
||||||
|
} {dynamic juliet flipper command | journal sherman ammonia helena | journal sherman gamma patriot | arctic sleep ammonia helena |}
|
||||||
|
|
||||||
|
if 0 {
|
||||||
|
# Trying to insert a duplicate PRIMARY KEY fails.
|
||||||
|
#
|
||||||
|
do_test without_rowid1-1.21 {
|
||||||
|
catchsql {
|
||||||
|
INSERT INTO t1 VALUES('dynamic','phone','flipper','harvard');
|
||||||
|
}
|
||||||
|
} {1 {columns c, a are not unique}}
|
||||||
|
|
||||||
|
# REPLACE INTO works, however.
|
||||||
|
#
|
||||||
|
do_execsql_test without_rowid1-1.22 {
|
||||||
|
REPLACE INTO t1 VALUES('dynamic','phone','flipper','harvard');
|
||||||
|
SELECT *, '|' FROM t1 ORDER BY c, a;
|
||||||
|
} {}
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_test
|
Reference in New Issue
Block a user