From 1421d980c57a9c0e62e746d9840d4ec6f0f8693f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 May 2015 03:46:18 +0000 Subject: [PATCH 1/2] Add the "PRAGMA cell_size_check=ON" command. FossilOrigin-Name: 2ead43f074d01312c7642e1df9abccc95547f019 --- Makefile.in | 2 +- main.mk | 2 +- manifest | 31 +++++++++++++++++-------------- manifest.uuid | 2 +- src/btree.c | 23 +++++------------------ src/main.c | 3 +++ src/pragma.h | 6 +++++- src/sqliteInt.h | 1 + test/fuzzcheck.c | 6 ++++++ tool/mkpragmatab.tcl | 4 ++++ 10 files changed, 44 insertions(+), 36 deletions(-) diff --git a/Makefile.in b/Makefile.in index cc994488b0..626fe92584 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1002,7 +1002,7 @@ test: $(TESTPROGS) fuzztest # because valgrind is so much slower than a native machine. # valgrindtest: $(TESTPROGS) fuzzcheck$(TEXE) - valgrind -v ./fuzzcheck$(TEXE) $(FUZZDATA) + valgrind -v ./fuzzcheck$(TEXE) --cell-size-check $(FUZZDATA) OMIT_MISUSE=1 valgrind -v ./testfixture$(TEXE) $(TOP)/test/permutations.test valgrind # A very fast test that checks basic sanity. The name comes from diff --git a/main.mk b/main.mk index bb17a17d80..9d37aebfd5 100644 --- a/main.mk +++ b/main.mk @@ -683,7 +683,7 @@ test: $(TESTPROGS) fuzztest # because valgrind is so much slower than a native machine. # valgrindtest: $(TESTPROGS) fuzzcheck$(EXE) $(FUZZDATA) - valgrind -v ./fuzzcheck$(EXE) $(FUZZDATA) + valgrind -v ./fuzzcheck$(EXE) --cell-size-check $(FUZZDATA) OMIT_MISUSE=1 valgrind -v ./testfixture$(EXE) $(TOP)/test/permutations.test valgrind # A very fast test that checks basic sanity. The name comes from diff --git a/manifest b/manifest index 7d61d9fee0..425bb14cc1 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,7 @@ -C Avoid\sa\sbuffer\soverread\swhen\scomparing\sagainst\sa\scorrupt\srecord\sthat\sspans\sat\sleast\sone\soverflow\spage. -D 2015-05-26T20:31:20.007 +C Add\sthe\s"PRAGMA\scell_size_check=ON"\scommand. +D 2015-05-27T03:46:18.035 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 3feb7cbdad8898fe7a8a24355b4a753029c3ec3b +F Makefile.in afc69c576d95c25380e973496434be5f85204fa7 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc d37d2c2323df3acae6e24c71a478889421c17264 F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 @@ -171,7 +171,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 031e36b22e2be9b9fdab086fd3115fc88c2e37bd +F main.mk 7c4a0434aafc8537cfe972a8644039411a63b5bb F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk d5e22023b5238985bb54a72d33e0ac71fe4f8a32 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -192,7 +192,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c ff743689c4d6c5cb55ad42ed9d174b2b3e71f1e3 F src/bitvec.c 5eb7958c3bf65210211cbcfc44eff86d0ded7c9d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 51cafeb18184dcb46285120d5574da6e19c58362 +F src/btree.c 5905cbd1436d36908cf68a42145a43efb650ac34 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4 F src/build.c 9552e7490b0310a8c73fcf3a0c36e7624789d8df @@ -215,7 +215,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c 29255bbe1cfb2ce9bbff2526a5ecfddcb49b9271 -F src/main.c bf14bc6a321965e528d8ab30087e9440335f2e4b +F src/main.c 3a610587018485d9a12e38899dd8b8129b04d836 F src/malloc.c 908c780fdddd472163c2d1b1820ae4081f01ad20 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c abe6ee469b6c5a35c7f22bfeb9c9bac664a1c987 @@ -244,7 +244,7 @@ F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8 F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9 F src/pragma.c c1f4d012ea9f6b1ce52d341b2cd0ad72d560afd7 -F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f +F src/pragma.h b8632d7cdda7b25323fa580e3e558a4f0d4502cc F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 13ce37e5574f9b0682fa86dbcf9faf76b9d82a15 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 @@ -255,7 +255,7 @@ F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee F src/sqlite.h.in 4d0ecd8e1e0272d9a2742b39602f5e4fad8d3246 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 2ebeb634e751a61a6f0eebfa0f4669f46a42f6cd -F src/sqliteInt.h 26484793b2f8017960b30ae2d0cbc7512eff5b17 +F src/sqliteInt.h a45d51a1ba1add61b221c33c21ceb12dc336adeb F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -651,7 +651,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 F test/fuzz3.test efd384b896c647b61a2c1848ba70d42aad60a7b3 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 -F test/fuzzcheck.c 348c2ac1ef3fde2eb7d312d5bf6fbf7ff42033b3 +F test/fuzzcheck.c c7dde1815b4a3973f6232fa474646c082b5579a1 F test/fuzzdata1.db b60254eeb6bc11474071b883059662a73c48da7f F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db 57ae47d2a1c837fb8ddc10ce4ab56a04ad044cb4 @@ -1241,7 +1241,7 @@ F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e -F tool/mkpragmatab.tcl 94f196c9961e0ca3513e29f57125a3197808be2d +F tool/mkpragmatab.tcl 40c287d3f929ece67da6e9e7c49885789960accf F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 69bae8ce4aa52d2ff82d4a8a856bf283ec035b2e F tool/mksqlite3c.tcl fdeab4c1eed90b7ab741ec12a7bc5c2fb60188bd @@ -1279,7 +1279,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b4a45d3b78fede2433ac18f20b1ab7bddee77059 -R f36cc3a04ab23b9a0c27493daaf0c4c0 -U dan -Z 4ff3966eaffa78ba4bc7061be84a775f +P 62a5b3633a086694ef0e579a0a82322cb1ae3d60 +R 010488f120297f349ac64bbd79d606ed +T *branch * cell-size-check-pragma +T *sym-cell-size-check-pragma * +T -sym-trunk * +U drh +Z d748b29c905901d502dcb715608a92ad diff --git a/manifest.uuid b/manifest.uuid index 110675c7e0..0ef7b1e553 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62a5b3633a086694ef0e579a0a82322cb1ae3d60 \ No newline at end of file +2ead43f074d01312c7642e1df9abccc95547f019 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index bb3f92aaa3..f84824766b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1196,26 +1196,18 @@ static int defragmentPage(MemPage *pPage){ pc = get2byte(pAddr); testcase( pc==iCellFirst ); testcase( pc==iCellLast ); -#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) /* These conditions have already been verified in btreeInitPage() - ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined + ** if PRAGMA cell_size_check=ON. */ if( pciCellLast ){ return SQLITE_CORRUPT_BKPT; } -#endif assert( pc>=iCellFirst && pc<=iCellLast ); size = cellSizePtr(pPage, &src[pc]); cbrk -= size; -#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) - if( cbrkusableSize ){ return SQLITE_CORRUPT_BKPT; } -#endif assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); testcase( cbrk+size==usableSize ); testcase( pc+size==usableSize ); @@ -1556,6 +1548,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ static int btreeInitPage(MemPage *pPage){ assert( pPage->pBt!=0 ); + assert( pPage->pBt->db!=0 ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); @@ -1614,8 +1607,7 @@ static int btreeInitPage(MemPage *pPage){ */ iCellFirst = cellOffset + 2*pPage->nCell; iCellLast = usableSize - 4; -#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) - { + if( pBt->db->flags & SQLITE_CellSizeCk ){ int i; /* Index into the cell pointer array */ int sz; /* Size of a cell */ @@ -1635,7 +1627,6 @@ static int btreeInitPage(MemPage *pPage){ } if( !pPage->leaf ) iCellLast++; } -#endif /* Compute the total free space on the page ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the @@ -4951,22 +4942,18 @@ int sqlite3BtreeMovetoUnpacked( /* The record flows over onto one or more overflow pages. In ** this case the whole cell needs to be parsed, a buffer allocated ** and accessPayload() used to retrieve the record into the - ** buffer before VdbeRecordCompare() can be called. An extra - ** byte of zeroed padding is allocated at the end of the buffer, - ** as this stops the record-compare routines from reading past - ** the end of the buffer if the record is corrupt. */ + ** buffer before VdbeRecordCompare() can be called. */ void *pCellKey; u8 * const pCellBody = pCell - pPage->childPtrSize; btreeParseCellPtr(pPage, pCellBody, &pCur->info); nCell = (int)pCur->info.nKey; - pCellKey = sqlite3Malloc( nCell+1 ); + pCellKey = sqlite3Malloc( nCell ); if( pCellKey==0 ){ rc = SQLITE_NOMEM; goto moveto_finish; } pCur->aiIdx[pCur->iPage] = (u16)idx; rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2); - ((unsigned char *)pCellKey)[nCell] = 0; if( rc ){ sqlite3_free(pCellKey); goto moveto_finish; diff --git a/src/main.c b/src/main.c index 83d0b99135..ef37b7e1a1 100644 --- a/src/main.c +++ b/src/main.c @@ -2758,6 +2758,9 @@ static int openDatabase( #endif #if defined(SQLITE_REVERSE_UNORDERED_SELECTS) | SQLITE_ReverseOrder +#endif +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + | SQLITE_CellSizeCk #endif ; sqlite3HashInit(&db->aCollSeq); diff --git a/src/pragma.h b/src/pragma.h index c9ae8e6eb8..bbf141ee2d 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -99,6 +99,10 @@ static const struct sPragmaNames { /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, /* ePragFlag: */ 0, /* iArg: */ 0 }, + { /* zName: */ "cell_size_check", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlag: */ 0, + /* iArg: */ SQLITE_CellSizeCk }, #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) { /* zName: */ "checkpoint_fullfsync", /* ePragTyp: */ PragTyp_FLAG, @@ -456,4 +460,4 @@ static const struct sPragmaNames { /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode }, #endif }; -/* Number of pragmas: 59 on by default, 72 total. */ +/* Number of pragmas: 60 on by default, 73 total. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index cba17d711a..c56bb43441 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1253,6 +1253,7 @@ struct sqlite3 { #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ #define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */ #define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */ +#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */ /* diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index fe5eb2d9d5..24eac48e33 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -596,6 +596,7 @@ static void showHelp(void){ "Read databases and SQL scripts from SOURCE-DB and execute each script against\n" "each database, checking for crashes and memory leaks.\n" "Options:\n" +" --cell-size-check Set the PRAGMA cell_size_check=ON\n" " --dbid N Use only the database where dbid=N\n" " --help Show this help text\n" " -q Reduced output\n" @@ -634,6 +635,7 @@ int main(int argc, char **argv){ int nTest = 0; /* Total number of tests performed */ char *zDbName = ""; /* Appreviated name of a source database */ const char *zFailCode = 0; /* Value of the TEST_FAILURE environment variable */ + int cellSzCkFlag = 0; /* --cell-size-check */ iBegin = timeOfDay(); g.zArgv0 = argv[0]; @@ -643,6 +645,9 @@ int main(int argc, char **argv){ if( z[0]=='-' ){ z++; if( z[0]=='-' ) z++; + if( strcmp(z,"cell-size-check")==0 ){ + cellSzCkFlag = 1; + }else if( strcmp(z,"dbid")==0 ){ if( i>=argc-1 ) fatalError("missing arguments on %s", argv[i]); onlyDbid = atoi(argv[++i]); @@ -825,6 +830,7 @@ int main(int argc, char **argv){ } rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs); if( rc ) fatalError("cannot open inmem database"); + if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags); runSql(db, (char*)pSql->a, runFlags); sqlite3_close(db); if( sqlite3_memory_used()>0 ) fatalError("memory leak"); diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 964946e788..cb3aed0fff 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -136,6 +136,10 @@ set pragma_def { IF: !defined(SQLITE_OMIT_FLAG_PRAGMAS) IF: !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + NAME: cell_size_check + TYPE: FLAG + ARG: SQLITE_CellSizeCk + NAME: default_cache_size FLAG: NeedSchema IF: !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) From fccda8a162b99c9419c6bccad4d88459a4c2dc81 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 May 2015 13:06:55 +0000 Subject: [PATCH 2/2] CTEs have never add working rowids. So disallow the use of the "rowid" column within CTEs. FossilOrigin-Name: 0055df0445932a43e42b318ef88672dcbe312c3a --- manifest | 29 ++++++++++++++++------------- manifest.uuid | 2 +- src/build.c | 2 +- src/parse.y | 2 +- src/resolve.c | 4 ++-- src/select.c | 2 +- src/sqliteInt.h | 6 ++++-- test/with1.test | 9 +++++++++ test/without_rowid1.test | 19 +++++++++++++++++++ 9 files changed, 54 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 7d61d9fee0..d66700a24b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\sbuffer\soverread\swhen\scomparing\sagainst\sa\scorrupt\srecord\sthat\sspans\sat\sleast\sone\soverflow\spage. -D 2015-05-26T20:31:20.007 +C CTEs\shave\snever\sadd\sworking\srowids.\s\sSo\sdisallow\sthe\suse\sof\sthe\s"rowid"\scolumn\nwithin\sCTEs. +D 2015-05-27T13:06:55.466 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 3feb7cbdad8898fe7a8a24355b4a753029c3ec3b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -195,7 +195,7 @@ F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c 51cafeb18184dcb46285120d5574da6e19c58362 F src/btree.h 969adc948e89e449220ff0ff724c94bb2a52e9f1 F src/btreeInt.h 973a22a6fd61350b454ad614832b1f0a5e25a1e4 -F src/build.c 9552e7490b0310a8c73fcf3a0c36e7624789d8df +F src/build.c 85a169a0a22f8b80caf513eaf2944d39b979f571 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c a5cf5b4b56390cfb7b8636e8f7ddef90258dd575 F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b @@ -239,7 +239,7 @@ F src/os_win.c 97f7828a9554d753665b6fcf7540e31c2b3d6a6e F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 9bc918a009285f96ec6dac62dd764c7063552455 F src/pager.h c3476e7c89cdf1c6914e50a11f3714e30b4e0a77 -F src/parse.y af55d4fb5e588705112e9788364ca3af09651fcf +F src/parse.y 44e1605840c1662e08b05e175eb8bb13b9172662 F src/pcache.c 10539fb959849ad6efff80050541cab3d25089d4 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8 F src/pcache1.c 69d137620a305f814398bd29a0c998038c0695e9 @@ -248,14 +248,14 @@ F src/pragma.h 09c89bca58e9a44de2116cc8272b8d454657129f F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 13ce37e5574f9b0682fa86dbcf9faf76b9d82a15 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 -F src/resolve.c 99eabf7eff0bfa65b75939b46caa82e2b2133f28 +F src/resolve.c 84c571794e3ee5806274d95158a4c0177c6c4708 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 9d9f6975bb538cafc5d4ae4a45565f15f5d296ff +F src/select.c 4dcc45372759f98754cd6171e48ec2b592fae9b7 F src/shell.c 07dda7cd692911d2f22269953418d049f2e2c0ee F src/sqlite.h.in 4d0ecd8e1e0272d9a2742b39602f5e4fad8d3246 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 2ebeb634e751a61a6f0eebfa0f4669f46a42f6cd -F src/sqliteInt.h 26484793b2f8017960b30ae2d0cbc7512eff5b17 +F src/sqliteInt.h 01d0b8741584a827c348d663cf09dcc7830b8ab3 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -1212,10 +1212,10 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d -F test/with1.test a86bf7f9288ba759a25ee57221d3bffaca36032a +F test/with1.test e99845d4f4bf7863b61f104de554c61739d65764 F test/with2.test ee227a663586aa09771cafd4fa269c5217eaf775 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 -F test/without_rowid1.test 4cda656cb4a452296e0d8d8623513f4be80c6d86 +F test/without_rowid1.test 1a7b9bd51b899928d327052df9741d2fe8dbe701 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test 1081aabf60a1e1123b7f9a8f6ae19954351843b0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a @@ -1279,7 +1279,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b4a45d3b78fede2433ac18f20b1ab7bddee77059 -R f36cc3a04ab23b9a0c27493daaf0c4c0 -U dan -Z 4ff3966eaffa78ba4bc7061be84a775f +P 62a5b3633a086694ef0e579a0a82322cb1ae3d60 +R aaa91eb8edb393c58a97feb3495d55b8 +T *branch * no-rowid-in-cte +T *sym-no-rowid-in-cte * +T -sym-trunk * +U drh +Z 4d193f313220f26215dcddc13be0f0b2 diff --git a/manifest.uuid b/manifest.uuid index 110675c7e0..1d4ac26538 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62a5b3633a086694ef0e579a0a82322cb1ae3d60 \ No newline at end of file +0055df0445932a43e42b318ef88672dcbe312c3a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 1cf427b033..ac423a2856 100644 --- a/src/build.c +++ b/src/build.c @@ -1844,7 +1844,7 @@ void sqlite3EndTable( if( (p->tabFlags & TF_HasPrimaryKey)==0 ){ sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); }else{ - p->tabFlags |= TF_WithoutRowid; + p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; convertToWithoutRowidTable(pParse, p); } } diff --git a/src/parse.y b/src/parse.y index 72a0a6d222..4ee553cc33 100644 --- a/src/parse.y +++ b/src/parse.y @@ -166,7 +166,7 @@ create_table_args ::= AS select(S). { table_options(A) ::= . {A = 0;} table_options(A) ::= WITHOUT nm(X). { if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){ - A = TF_WithoutRowid; + A = TF_WithoutRowid | TF_NoVisibleRowid; }else{ A = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z); diff --git a/src/resolve.c b/src/resolve.c index 23636eacec..27eba9fd07 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -358,7 +358,7 @@ static int lookupName( break; } } - if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ + if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ /* IMP: R-51414-32910 */ /* IMP: R-44911-55124 */ iCol = -1; @@ -388,7 +388,7 @@ static int lookupName( ** Perhaps the name is a reference to the ROWID */ if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol) - && HasRowid(pMatch->pTab) ){ + && VisibleRowid(pMatch->pTab) ){ cnt = 1; pExpr->iColumn = -1; /* IMP: R-44911-55124 */ pExpr->affinity = SQLITE_AFF_INTEGER; diff --git a/src/select.c b/src/select.c index 5626bb070f..ad95719209 100644 --- a/src/select.c +++ b/src/select.c @@ -3991,7 +3991,7 @@ static int withExpand( pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - pTab->tabFlags |= TF_Ephemeral; + pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); if( db->mallocFailed ) return SQLITE_NOMEM; assert( pFrom->pSelect ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index cba17d711a..b55329fcea 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1634,8 +1634,9 @@ struct Table { #define TF_HasPrimaryKey 0x04 /* Table has a primary key */ #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */ #define TF_Virtual 0x10 /* Is a virtual table */ -#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */ -#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */ +#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */ +#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */ /* @@ -1653,6 +1654,7 @@ struct Table { /* Does the table have a rowid */ #define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0) +#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0) /* ** Each foreign key constraint is an instance of the following structure. diff --git a/test/with1.test b/test/with1.test index 80892d2642..8d8b6f75b5 100644 --- a/test/with1.test +++ b/test/with1.test @@ -849,4 +849,13 @@ do_execsql_test 14.1 { WITH x AS (SELECT * FROM t) SELECT 0 EXCEPT SELECT 0 ORDER BY 1 COLLATE binary; } {} +# 2015-05-27: Do not allow rowid usage within a CTE +# +do_catchsql_test 15.1 { + WITH RECURSIVE + d(x) AS (VALUES(1) UNION ALL SELECT rowid+1 FROM d WHERE rowid<10) + SELECT x FROM d; +} {1 {no such column: rowid}} + + finish_test diff --git a/test/without_rowid1.test b/test/without_rowid1.test index b746cca277..0c77773abb 100644 --- a/test/without_rowid1.test +++ b/test/without_rowid1.test @@ -308,6 +308,25 @@ do_execsql_test 6.1 { ok t48 sqlite_autoindex_t48_2 } +# 2015-05-28: CHECK constraints can refer to the rowid in a +# rowid table, but not in a WITHOUT ROWID table. +# +do_execsql_test 7.1 { + CREATE TABLE t70a( + a INT CHECK( rowid!=33 ), + b TEXT PRIMARY KEY + ); + INSERT INTO t70a(a,b) VALUES(99,'hello'); +} {} +do_catchsql_test 7.2 { + INSERT INTO t70a(rowid,a,b) VALUES(33,99,'xyzzy'); +} {1 {CHECK constraint failed: t70a}} +do_catchsql_test 7.3 { + CREATE TABLE t70b( + a INT CHECK( rowid!=33 ), + b TEXT PRIMARY KEY + ) WITHOUT ROWID; +} {1 {no such column: rowid}} finish_test