Compare commits

...

24 Commits

Author SHA1 Message Date
mistachkin b04275121c Enhance the MSVC makefile for better debugging symbol support.
FossilOrigin-Name: c723ec2784d6b60c9781a435c84800b2bc7818d5
2014-01-30 11:12:52 +00:00
drh ec2da85412 Make sure that sqlite3SelectDup() initializes the nSelectRow of the
duplicate Select object.

FossilOrigin-Name: 5bb29b82109224a2ad02920658fabd8fb0f27b3f
2014-01-29 01:46:12 +00:00
drh db718d8a3b Fix harmless compiler warnings in the showdb utility program.
FossilOrigin-Name: 27c27daa3324b7c9323acfb972330367630bb64e
2014-01-28 20:36:22 +00:00
drh 4d06798e56 Fix a potential over-size and hence undefined shift operation.
FossilOrigin-Name: 6379b0729521146bc4ec27a9924492c7dc1d8a31
2014-01-28 18:53:29 +00:00
dan 9c2552f2e8 Minor bugfix in main.c so that the library builds with SQLITE_OMIT_WSD defined.
FossilOrigin-Name: 5e3b9ecc7b2b2e50952de819b99bafdb7b9ff59e
2014-01-28 17:49:13 +00:00
dan 705a48758a Fix a couple of problems with new test scripts causing the permutations test to fail.
FossilOrigin-Name: 48d736c0ee1ac0879bd12d2f1901f208e87e538a
2014-01-27 16:35:15 +00:00
drh a820c05aa0 Update some requirements marks to conform with improvements
in the documentation.

FossilOrigin-Name: be1acb610f7e594b417dd8409b7a7aa8f3af5f77
2014-01-27 15:02:07 +00:00
dan d0879bad42 Fix a problem in pagerfault.test causing an assert() to fail.
FossilOrigin-Name: ba8d2d507f82e2baaceadcf7ac6d71bb91f7e06b
2014-01-27 14:19:22 +00:00
drh 729677720d Fix (harmless) duplicate variable declaration.
FossilOrigin-Name: 94ed9bc4207873e0f3f8114009002f56d5aff359
2014-01-27 13:58:58 +00:00
dan abfe034692 Fix some problems in test scripts. No code changes.
FossilOrigin-Name: 08acfc65877e207f1a62d31a14afb4add20c4c35
2014-01-27 08:48:10 +00:00
dan b68b97789e Fix a problem causing SQLITE_OMIT_COMPOUND_SELECT builds to fail.
FossilOrigin-Name: b30db0ac3096b43d55a6da40cafc7de569082bf8
2014-01-25 12:16:53 +00:00
drh 693e671936 Fixes for various clang warnings.
FossilOrigin-Name: 87bf60637e5863c54c5e2d05aaaca0835b7aace8
2014-01-24 22:58:00 +00:00
dan 53bed45ecb Select collation sequences for ORDER BY expressions attached to recursive CTEs in the same way as they are selected for other compound SELECT statements.
FossilOrigin-Name: 9554519c126c5e714421a82fd2e8aa9b19e11493
2014-01-24 20:37:18 +00:00
mistachkin 6ef5e12e1f Fix harmless compiler warnings in the Tcl interface.
FossilOrigin-Name: 35bc81f5ad4503c0db03127ba3c2ee4ce5227448
2014-01-24 17:03:55 +00:00
dan 05d3dc29c5 Add test cases for LIMIT and ORDER BY on recursive CTEs.
FossilOrigin-Name: 67d6c42d44cb191368ce20f553b32fcb14bfc4d7
2014-01-24 16:57:42 +00:00
drh dc3bb0deb2 Use an unsigned integer to accumulate the string hash. Avoids compiler
warnings.

FossilOrigin-Name: b1824344ea4918a13abbda4a3b7134d35fd867c4
2014-01-24 16:36:18 +00:00
drh 9e2c7ae1b0 Add a few more CTE test cases to closure.test.
FossilOrigin-Name: 1b6405d9788c1bb89761b2bcdce560a5020ff503
2014-01-24 15:42:51 +00:00
drh 3c2aeae16e Add test cases that compare the performance of the transitive_closure
virtual table again common table expressions for walking a tree.

FossilOrigin-Name: 9a23f020e8ed0e7a1ad227b4ab379fdf5e2de222
2014-01-24 14:37:44 +00:00
drh b090352b5a Add test cases showing the use of ORDER BY on a recursive query to control
depth-first versus breath-first search of a tree.

FossilOrigin-Name: 83b0b2916589db0184435dbd4c304387f393ed60
2014-01-24 11:16:01 +00:00
dan afcf9bd806 Modifications to test files to omit any tests that intentionally access out-of-bounds locations in clang -fsanitize=address builds.
FossilOrigin-Name: f4a701d55f5c4e1e62ed64b779ad4fff89dd31b7
2014-01-23 14:44:08 +00:00
dan cfe24586a8 Avoid an extra seek when inserting records into the epheremal index used to ensure that rows returned by UNION recursive queries are unique.
FossilOrigin-Name: 72c4b3f07a3faacb5b62d5bc374b4e125a0bd8b3
2014-01-22 19:23:30 +00:00
drh edf83d1e3d Fix harmless compiler warnings.
FossilOrigin-Name: dea2ca6a159d5dcfd8deceedf1c2a73fb4ac1cfc
2014-01-22 18:31:27 +00:00
drh 953dfa4e60 Change the WITH RECURSIVE implementation to use a queue instead of a pair of
tables.  Add support for ORDER BY, LIMIT, and OFFSET on recursive queries.

FossilOrigin-Name: b6cea42006910d590373e8f9e296d7672edb114b
2014-01-22 18:16:27 +00:00
dan a8a0617e06 Update the spellfix virtual table to optimize queries of the form "SELECT ... FROM tbl WHERE rowid=?".
FossilOrigin-Name: a0ba55ff0596c5f15e9cdb254c68ef50df2dfaad
2014-01-22 17:43:16 +00:00
41 changed files with 945 additions and 323 deletions
+21 -10
View File
@@ -270,6 +270,17 @@ TCC = $(TCC) -I$(TOP)\ext\rtree
RCC = $(RCC) -I$(TOP)\ext\rtree
!ENDIF
# The mksqlite3c.tcl script accepts some options on the command
# line. When compiling with debugging enabled, some of these
# options are necessary in order to allow debugging symbols to
# work correctly with Visual Studio when using the amalgamation.
#
!IF $(DEBUG)>0
MKSQLITE3C_ARGS = --linemacros
!ELSE
MKSQLITE3C_ARGS =
!ENDIF
# Define -DNDEBUG to compile without debugging (i.e., for production usage)
# Omitting the define will cause extra debugging code to be inserted and
# includes extra comments when "EXPLAIN stmt" is used.
@@ -916,7 +927,7 @@ mptester.exe: $(TOP)\mptest\mptest.c libsqlite3.lib $(LIBRESOBJS) sqlite3.h
echo > .target_source
sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl
$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS)
copy tsrc\shell.c .
copy tsrc\sqlite3ext.h .
@@ -1334,17 +1345,17 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS)
$(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \
/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
showdb.exe: $(TOP)\tool\showdb.c sqlite3.c
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \
$(TOP)\tool\showdb.c sqlite3.c
showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C)
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\tool\showdb.c $(SQLITE3C)
wordcount.exe: $(TOP)\test\wordcount.c sqlite3.c
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \
$(TOP)\test\wordcount.c sqlite3.c
wordcount.exe: $(TOP)\test\wordcount.c $(SQLITE3C)
$(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\test\wordcount.c $(SQLITE3C)
speedtest1.exe: $(TOP)\test\speedtest1.c sqlite3.c
$(LTLINK) -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \
$(TOP)\test\speedtest1.c sqlite3.c
speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C)
$(LTLINK) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
$(TOP)\test\speedtest1.c $(SQLITE3C)
clean:
del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
+2 -2
View File
@@ -96,13 +96,13 @@ void sqlite3Fts3HashClear(Fts3Hash *pH){
*/
static int fts3StrHash(const void *pKey, int nKey){
const char *z = (const char *)pKey;
int h = 0;
unsigned h = 0;
if( nKey<=0 ) nKey = (int) strlen(z);
while( nKey > 0 ){
h = (h<<3) ^ h ^ *z++;
nKey--;
}
return h & 0x7fffffff;
return (int)(h & 0x7fffffff);
}
static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
if( n1!=n2 ) return 1;
+28 -4
View File
@@ -2051,6 +2051,7 @@ static int spellfix1Close(sqlite3_vtab_cursor *cur){
** (D) scope = $scope
** (E) distance < $distance
** (F) distance <= $distance
** (G) rowid = $rowid
**
** The plan number is a bit mask formed with these bits:
**
@@ -2060,8 +2061,9 @@ static int spellfix1Close(sqlite3_vtab_cursor *cur){
** 0x08 (D) is found
** 0x10 (E) is found
** 0x20 (F) is found
** 0x40 (G) is found
**
** filter.argv[*] values contains $str, $langid, $top, and $scope,
** filter.argv[*] values contains $str, $langid, $top, $scope and $rowid
** if specified and in that order.
*/
static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
@@ -2070,6 +2072,7 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int iTopTerm = -1;
int iScopeTerm = -1;
int iDistTerm = -1;
int iRowidTerm = -1;
int i;
const struct sqlite3_index_constraint *pConstraint;
pConstraint = pIdxInfo->aConstraint;
@@ -2122,6 +2125,15 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
iPlan |= pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ? 16 : 32;
iDistTerm = i;
}
/* Terms of the form: distance < $dist or distance <= $dist */
if( (iPlan & 64)==0
&& pConstraint->iColumn<0
&& pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ
){
iPlan |= 64;
iRowidTerm = i;
}
}
if( iPlan&1 ){
int idx = 2;
@@ -2149,6 +2161,11 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->aConstraintUsage[iDistTerm].omit = 1;
}
pIdxInfo->estimatedCost = 1e5;
}else if( (iPlan & 64) ){
pIdxInfo->idxNum = 64;
pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1;
pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1;
pIdxInfo->estimatedCost = 5;
}else{
pIdxInfo->idxNum = 0;
pIdxInfo->estimatedCost = 1e50;
@@ -2465,16 +2482,23 @@ static int spellfix1FilterForFullScan(
int argc,
sqlite3_value **argv
){
int rc;
int rc = SQLITE_OK;
char *zSql;
spellfix1_vtab *pVTab = pCur->pVTab;
spellfix1ResetCursor(pCur);
assert( idxNum==0 || idxNum==64 );
zSql = sqlite3_mprintf(
"SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"",
pVTab->zDbName, pVTab->zTableName);
"SELECT word, rank, NULL, langid, id FROM \"%w\".\"%w_vocab\"%s",
pVTab->zDbName, pVTab->zTableName,
((idxNum & 64) ? " WHERE rowid=?" : "")
);
if( zSql==0 ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pFullScan, 0);
sqlite3_free(zSql);
if( rc==SQLITE_OK && (idxNum & 64) ){
assert( argc==1 );
rc = sqlite3_bind_value(pCur->pFullScan, 1, argv[0]);
}
pCur->nRow = pCur->iRow = 0;
if( rc==SQLITE_OK ){
rc = sqlite3_step(pCur->pFullScan);
+48 -45
View File
@@ -1,9 +1,9 @@
C Add\ssupport\sfor\sLIMIT\sand\sOFFSET\sin\sa\srecursive\squery.
D 2014-01-22T18:07:04.473
C Enhance\sthe\sMSVC\smakefile\sfor\sbetter\sdebugging\ssymbol\ssupport.
D 2014-01-30T11:12:52.221
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 4d4ead6b71d1bf03028fbd61da0ba0ec5e1556e1
F Makefile.msc 6ff3ff2eef45c7dd309a8626ff7947b20bd387e7
F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION 8ed548d87d0a27fd7d7620476f9e25f9fa742d73
@@ -83,7 +83,7 @@ F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
F ext/fts3/fts3_hash.c 29b986e43f4e9dd40110eafa377dc0d63c422c60
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
F ext/fts3/fts3_porter.c 7f8b4bf5af7c0f20f73b8e87e14fa9298f52e290
@@ -114,7 +114,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/spellfix.c 76578f2c56ceaa23d22032338d90db79c68490fb
F ext/misc/spellfix.c adfc569fafef7a1eb8f21528e5277686b358c3ce
F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512
F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95
F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
@@ -174,13 +174,13 @@ F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff
F src/expr.c 8c7e482bc8f7982333f046851a610ccdb8a1ba94
F src/delete.c d784e2ee2c6e90fbbd9dcf88a2030c9e12a9318d
F src/expr.c e3e09af908b968305d4efeda8dc3499a087ee7d2
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5
F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19
F src/func.c f4499b39d66b71825514334ce67b32ff14bd19f5
F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c a4450f0c46a9f221622e6551ab0953b03c4f8ee8
@@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c 4a05a9706579c7649d7eebb0094586728eb53fcb
F src/main.c 07225af6a00be0b7f34ac52e60f99cf5cbb2a475
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
@@ -205,38 +205,38 @@ F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968
F src/os_unix.c f3ed0e406cbf9c820565b2118232d0796346130f
F src/os_win.c 1b21af72c5fa6f9e519a5fcab33e80d182b1aedb
F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y 475896cb883bbf4782e98abda42efbbdcbdb75f5
F src/parse.y bd51bc17cbfe7549adb4ca3747b1c3d384645065
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b
F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c
F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c f6d84f3a109d3e43d38089da6a4f131a5ce4c6ef
F src/select.c a421f3fb7f52a3c0b37f5caeabd27799e8a9ae58
F src/shell.c 24722d24d4ea8ca93db35e44db7308de786767ca
F src/sqlite.h.in eed7f7d66a60daaa7b4a597dcd9bad87aad9611b
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 87a90ad4818ac5d68d3463eb7fe3ed96e5209b25
F src/sqliteInt.h 22c8f7112f2fa8e778bbd9d331cbebff8c645574
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 46073db71011b6542fde1f234c56a076d5ff23f9
F src/test1.c db16ba651453b15001c7f2838c446284dde4ecaf
F src/tclsqlite.c 21ca0043d7c48cde5dabed5c1116eee1be692f62
F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723
F src/test7.c 72b732baa5642f795655ba1126ea032af46ecfd2
F src/test8.c c7aab1d9fbbf54fc33d43b73aa24aa55f9eaf534
F src/test8.c 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
@@ -276,17 +276,17 @@ F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 6da2de6e12218ccb0aea5184b56727d011f4bee7
F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98
F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb
F src/update.c a7df6fffce6bfedc578fda6136dd33e34a63f8ee
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c
F src/util.c 15ac2627f548f5481d0d7e6c4eb67be673027695
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c dede894c2990329f8bc5a70da7de44ce8c3c6bf5
F src/vdbe.c 5fe94e13fa56c50edb75263706b6fbcc860a3980
F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26
F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56
F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad
F src/vdbeaux.c 9f4bfc52672acbb0bb4493d6a03603dc5a595ac1
F src/vdbeaux.c a3327afa8cfcc5bb3d38f2b2a599bac5fb63c6be
F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33
F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2
F src/vdbemem.c 23cdc14ed43e0aafa57bd72b9bf3d5b1641afa91
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
@@ -364,15 +364,15 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa
F test/capi3.test 6cdd49656bd62a296924f4d2fcfd05cd2a298369
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0
F test/capi3c.test a21869e4d50d5dbb7e566e328fc0bc7c2efa6a32
F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0
F test/capi3e.test ad90088b18b0367125ff2d4b5400153fd2f99aab
F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3
F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7
F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test 73b91005f264b7c403e2d63a6708d150679ac99a
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
@@ -406,7 +406,7 @@ F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040
F test/corruptE.test 193b4ca4e927e77c1d5f4f56203ddc998432a7ee
F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4
F test/corruptG.test c150f156dace653c00a121ad0f5772a0568c41ba
F test/corruptH.test 0a247f3dc8a8f3578db5f639d86c6bb4d520207f
F test/corruptH.test 9d8186f6f8751efdfd445d8546fd98f073499039
F test/count.test 42a251178e32f617eda33f76236a7f79825a50b5
F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
@@ -439,13 +439,13 @@ F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a
F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412
F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306
F test/e_expr.test 5c71d183fbf519a4769fd2e2124afdc70b5b1f42
F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41
F test/e_fkey.test 630597377549af579d34faaf64c6959a5a68ef76
F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0
F test/e_reindex.test 396b7b4f0a66863b4e95116a67d93b227193e589
F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test d3226cb94fae4af3f198e68e71f655e106d0be47
F test/e_select2.test 22c660a7becf0712c95e1ca1b2d9e716a1261460
F test/e_select.test 51c062a9bda16e0ae1bbeed50806bedbd040b282
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
F test/e_update.test 312cb8f5ccfe41515a6bb092f8ea562a9bd54d52
F test/e_uri.test a2c92d80093a7efdcfbb11093651cbea87097b6b
F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9
@@ -700,8 +700,8 @@ F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test 1265eb98c2e22a446a13fdef754118b272716684
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2
F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912
F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
@@ -728,8 +728,8 @@ F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pager4.test b40ecb4cc7dff957ee7916e41ab21d1ed702a642
F test/pagerfault.test 7285379906ab2f1108b8e82bbdf2d386cc8ff3ff
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
F test/pagerfault.test ae9ee0db5a30aecda9db8290ce3dd12e5f7bbaa1
F test/pagerfault2.test caf4c7facb914fd3b03a17b31ae2b180c8d6ca1f
F test/pagerfault3.test 1003fcda009bf48a8e22a516e193b6ef0dd1bbd8
F test/pageropt.test 6b8f6a123a5572c195ad4ae40f2987007923bbd6
@@ -741,7 +741,7 @@ F test/permutations.test af3278cbea3a19e025d5169be8193ff48dc3f862
F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/printf2.test 414fcba6d6c10e0a5e58efd213811e5ead4635a0
F test/printf2.test bed79b4c3e5da08ba88ad637c0bf62586843cfb1
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
@@ -783,7 +783,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054
F test/select4.test 00179be44e531fe04c1c3f15df216439dff2519d
F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535
F test/select6.test e76bd10a56988f15726c097a5d5a7966fe82d3b2
F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe
F test/select7.test 7fd2ef598cfabb6b9ff6ac13973b91d0527df49d
F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d
F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95
F test/selectA.test 99cf21df033b93033ea4f34aba14a500f48f04fe
@@ -825,7 +825,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4
F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be
F test/spellfix.test 61309f5efbec53603b3f86457d34a504f80abafe
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
@@ -844,7 +844,7 @@ F test/tclsqlite.test 37a61c2da7e3bfe3b8c1a2867199f6b860df5d43
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl 08e9f317afe60d398fa900993503ecaef3295bad
F test/tester.tcl 9bd04481b8b0ef1f2049ad01f28e175ee9a14f7b
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1092,7 +1092,7 @@ F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
F test/with1.test 97166cc72de5327bbae782aece707c45ee40e41b
F test/with1.test ce15d69d34a2576b0e47d78c244d1ba2a31679d1
F test/with2.test 2fe78fcd8deef2a0f9cfc49bfc755911d0b3fd64
F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991
F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
@@ -1127,12 +1127,12 @@ F tool/mksqlite3h.tcl ba24038056f51fde07c0079c41885ab85e2cff12
F tool/mksqlite3internalh.tcl 3dca7bb5374cee003379b8cbac73714f610ef795
F tool/mkvsix.tcl 6477fb9dab838b7eea1eed50658ff1cda04850b5
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 4665982e95a6e5c1bd806cf7bc3dea95be422d77
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c 525ecc443578647703051308ad50a93de6ba2c4b
F tool/showdb.c 1f3fe634d6f690b8d39ab1b9fd34583d468921e1
F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
@@ -1152,7 +1152,10 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 37b343b01841b338954ddfa9b76d92aa50037aec
R f6fa1b44c6431db29f11962241b14895
U drh
Z a802989c6813792648a40d2b5db727ef
P 5bb29b82109224a2ad02920658fabd8fb0f27b3f
R e0401798681e1755ee5c5e2fa367c3e2
T *branch * msvcDebug
T *sym-msvcDebug *
T -sym-trunk *
U mistachkin
Z 7b0fb43b6887cb799be56b64c1e1c153
+1 -1
View File
@@ -1 +1 @@
1945484e6b9769c1943f750f5b09860417fb190a
c723ec2784d6b60c9781a435c84800b2bc7818d5
+3 -1
View File
@@ -636,7 +636,9 @@ void sqlite3GenerateRowDelete(
** used by any BEFORE and AFTER triggers that exist. */
sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
for(iCol=0; iCol<pTab->nCol; iCol++){
if( mask==0xffffffff || mask&(1<<iCol) ){
testcase( mask!=0xffffffff && iCol==31 );
testcase( mask!=0xffffffff && iCol==32 );
if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
}
}
+7 -7
View File
@@ -1064,6 +1064,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->addrOpenEphm[2] = -1;
pNew->nSelectRow = p->nSelectRow;
pNew->pWith = withDup(db, p->pWith);
return pNew;
}
@@ -1584,11 +1585,9 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
iCol = (i16)pExpr->iColumn;
/* Code an OP_VerifyCookie and OP_TableLock for <table>. */
if( ALWAYS(pTab->pSchema) ){
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
/* This function is only called from two places. In both cases the vdbe
** has already been allocated. So assume sqlite3GetVdbe() is always
@@ -2687,7 +2686,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
FuncDef *pDef; /* The function definition object */
int nId; /* Length of the function name in bytes */
const char *zId; /* The function name */
int constMask = 0; /* Mask of function arguments that are constant */
u32 constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
@@ -2738,7 +2737,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
for(i=0; i<nFarg; i++){
if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
constMask |= (1<<i);
testcase( i==31 );
constMask |= MASKBIT32(i);
}
if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
+1 -1
View File
@@ -137,7 +137,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
case SQLITE_INTEGER: {
i64 iVal = sqlite3_value_int64(argv[0]);
if( iVal<0 ){
if( (iVal<<1)==0 ){
if( iVal==SMALLEST_INT64 ){
/* IMP: R-31676-45509 If X is the integer -9223372036854775808
** then abs(X) throws an integer overflow error since there is no
** equivalent positive 64-bit two complement value. */
+1 -1
View File
@@ -53,7 +53,7 @@ void sqlite3HashClear(Hash *pH){
** The hashing function.
*/
static unsigned int strHash(const char *z, int nKey){
int h = 0;
unsigned int h = 0;
assert( nKey>=0 );
while( nKey > 0 ){
h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
+1 -1
View File
@@ -3303,7 +3303,7 @@ int sqlite3_test_control(int op, ...){
** that demonstrat invariants on well-formed database files.
*/
case SQLITE_TESTCTRL_NEVER_CORRUPT: {
sqlite3Config.neverCorrupt = va_arg(ap, int);
sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int);
break;
}
+1 -1
View File
@@ -4097,7 +4097,7 @@ static int unixShmSystemLock(
#ifdef SQLITE_DEBUG
{ u16 mask;
OSTRACE(("SHM-LOCK "));
mask = ofst>31 ? 0xffffffff : (1<<(ofst+n)) - (1<<ofst);
mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
if( rc==SQLITE_OK ){
if( lockType==F_UNLCK ){
OSTRACE(("unlock %d ok", ofst));
+1 -1
View File
@@ -397,7 +397,7 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). {
//////////////////////// The SELECT statement /////////////////////////////////
//
cmd ::= select(X). {
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
sqlite3Select(pParse, X, &dest);
sqlite3ExplainBegin(pParse->pVdbe);
sqlite3ExplainSelect(pParse->pVdbe, X);
+2 -1
View File
@@ -720,6 +720,7 @@ static sqlite3_pcache_page *pcache1Fetch(
PGroup *pGroup;
PgHdr1 *pPage = 0;
assert( offsetof(PgHdr1,page)==0 );
assert( pCache->bPurgeable || createFlag!=1 );
assert( pCache->bPurgeable || pCache->nMin==0 );
assert( pCache->bPurgeable==0 || pCache->nMin==10 );
@@ -825,7 +826,7 @@ fetch_out:
pCache->iMaxKey = iKey;
}
pcache1LeaveMutex(pGroup);
return &pPage->page;
return (sqlite3_pcache_page*)pPage;
}
+49 -29
View File
@@ -814,6 +814,7 @@ static void selectInnerLoop(
** been added */
addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, r3, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
}
for(i=0; i<nKey; i++){
sqlite3VdbeAddOp2(v, OP_SCopy,
@@ -1724,7 +1725,44 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
}
return pRet;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */
/*
** The select statement passed as the second parameter is a compound SELECT
** with an ORDER BY clause. This function allocates and returns a KeyInfo
** structure suitable for implementing the ORDER BY.
**
** Space to hold the KeyInfo structure is obtained from malloc. The calling
** function is responsible for ensuring that this structure is eventually
** freed.
*/
static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
ExprList *pOrderBy = p->pOrderBy;
int nOrderBy = p->pOrderBy->nExpr;
sqlite3 *db = pParse->db;
KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
if( pRet ){
int i;
for(i=0; i<nOrderBy; i++){
struct ExprList_item *pItem = &pOrderBy->a[i];
Expr *pTerm = pItem->pExpr;
CollSeq *pColl;
if( pTerm->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pTerm);
}else{
pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1);
if( pColl==0 ) pColl = db->pDfltColl;
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
assert( sqlite3KeyInfoIsWriteable(pRet) );
pRet->aColl[i] = pColl;
pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
}
}
return pRet;
}
#ifndef SQLITE_OMIT_CTE
/*
@@ -1774,7 +1812,7 @@ static void generateWithRecursiveQuery(
Select *pSetup = p->pPrior; /* The setup query */
int addrTop; /* Top of the loop */
int addrCont, addrBreak; /* CONTINUE and BREAK addresses */
int iCurrent; /* The Current table */
int iCurrent = 0; /* The Current table */
int regCurrent; /* Register holding Current table */
int iQueue; /* The Queue table */
int iDistinct = 0; /* To ensure unique results if UNION */
@@ -1798,6 +1836,7 @@ static void generateWithRecursiveQuery(
regOffset = p->iOffset;
p->pLimit = p->pOffset = 0;
p->iLimit = p->iOffset = 0;
pOrderBy = p->pOrderBy;
/* Locate the cursor number of the Current table */
for(i=0; ALWAYS(i<pSrc->nSrc); i++){
@@ -1807,10 +1846,6 @@ static void generateWithRecursiveQuery(
}
}
/* Detach the ORDER BY clause from the compound SELECT */
pOrderBy = p->pOrderBy;
p->pOrderBy = 0;
/* Allocate cursors numbers for Queue and Distinct. The cursor number for
** the Distinct table must be exactly one greater than Queue in order
** for the SRT_DistTable and SRT_DistQueue destinations to work. */
@@ -1827,7 +1862,7 @@ static void generateWithRecursiveQuery(
regCurrent = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol);
if( pOrderBy ){
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 1);
KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0,
(char*)pKeyInfo, P4_KEYINFO);
destQueue.pOrderBy = pOrderBy;
@@ -1840,6 +1875,9 @@ static void generateWithRecursiveQuery(
p->selFlags |= SF_UsesEphemeral;
}
/* Detach the ORDER BY clause from the compound SELECT */
p->pOrderBy = 0;
/* Store the results of the setup-query in Queue. */
rc = sqlite3Select(pParse, pSetup, &destQueue);
if( rc ) goto end_of_recursive_query;
@@ -1882,7 +1920,7 @@ end_of_recursive_query:
p->pOffset = pOffset;
return;
}
#endif
#endif /* SQLITE_OMIT_CTE */
/* Forward references */
static int multiSelectOrderBy(
@@ -1892,7 +1930,6 @@ static int multiSelectOrderBy(
);
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine is called to process a compound query form from
** two or more separate queries using UNION, UNION ALL, EXCEPT, or
@@ -1936,8 +1973,8 @@ static int multiSelect(
Select *pDelete = 0; /* Chain of simple selects to delete */
sqlite3 *db; /* Database connection */
#ifndef SQLITE_OMIT_EXPLAIN
int iSub1; /* EQP id of left-hand query */
int iSub2; /* EQP id of right-hand query */
int iSub1 = 0; /* EQP id of left-hand query */
int iSub2 = 0; /* EQP id of right-hand query */
#endif
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
@@ -2624,24 +2661,7 @@ static int multiSelectOrderBy(
&& pItem->u.x.iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1);
if( pKeyMerge ){
for(i=0; i<nOrderBy; i++){
CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr;
if( pTerm->flags & EP_Collate ){
pColl = sqlite3ExprCollSeq(pParse, pTerm);
}else{
pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
if( pColl==0 ) pColl = db->pDfltColl;
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
assert( sqlite3KeyInfoIsWriteable(pKeyMerge) );
pKeyMerge->aColl[i] = pColl;
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
}
}
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
}else{
pKeyMerge = 0;
}
+1
View File
@@ -1982,6 +1982,7 @@ typedef u64 Bitmask;
** A bit in a Bitmask
*/
#define MASKBIT(n) (((Bitmask)1)<<(n))
#define MASKBIT32(n) (((unsigned int)1)<<(n))
/*
** The following structure describes the FROM clause of a SELECT statement.
+8 -8
View File
@@ -873,7 +873,7 @@ static int auth_callback(
const char *zArg3,
const char *zArg4
){
char *zCode;
const char *zCode;
Tcl_DString str;
int rc;
const char *zReply;
@@ -999,7 +999,7 @@ static int DbTransPostCmd(
Tcl_Interp *interp, /* Tcl interpreter */
int result /* Result of evaluating SCRIPT */
){
static const char *azEnd[] = {
static const char *const azEnd[] = {
"RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */
"COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */
"ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
@@ -1937,7 +1937,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
Tcl_AppendResult(interp, pDb->zCommit, 0);
}
}else{
char *zCommit;
const char *zCommit;
int len;
if( pDb->zCommit ){
Tcl_Free(pDb->zCommit);
@@ -2010,14 +2010,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
char *zSql; /* An SQL statement */
char *zLine; /* A single line of input from the file */
char **azCol; /* zLine[] broken up into columns */
char *zCommit; /* How to commit changes */
const char *zCommit; /* How to commit changes */
FILE *in; /* The input file */
int lineno = 0; /* Line number of input file */
char zLineNum[80]; /* Line number print buffer */
Tcl_Obj *pResult; /* interp result */
char *zSep;
char *zNull;
const char *zSep;
const char *zNull;
if( objc<5 || objc>7 ){
Tcl_WrongNumArgs(interp, 2, objv,
"CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
@@ -2935,7 +2935,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( objc==2 ){
zArg = Tcl_GetStringFromObj(objv[1], 0);
if( strcmp(zArg,"-version")==0 ){
Tcl_AppendResult(interp,sqlite3_version,0);
Tcl_AppendResult(interp,sqlite3_libversion(),0);
return TCL_OK;
}
if( strcmp(zArg,"-has-codec")==0 ){
@@ -3017,7 +3017,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
zErrMsg = 0;
p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
if( p==0 ){
Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
Tcl_SetResult(interp, (char *)"malloc failed", TCL_STATIC);
return TCL_ERROR;
}
memset(p, 0, sizeof(*p));
+23 -1
View File
@@ -242,7 +242,28 @@ static int test_io_trace(
return TCL_OK;
}
/*
** Usage: clang_sanitize_address
**
** Returns true if the program was compiled using clang with the
** -fsanitize=address switch on the command line. False otherwise.
*/
static int clang_sanitize_address(
void *NotUsed,
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
char **argv /* Text of each argument */
){
int res = 0;
#if defined(__has_feature)
# if __has_feature(address_sanitizer)
res = 1;
# endif
#endif
Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
return TCL_OK;
}
/*
** Usage: sqlite3_exec_printf DB FORMAT STRING
**
@@ -6323,6 +6344,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout },
{ "printf", (Tcl_CmdProc*)test_printf },
{ "sqlite3IoTrace", (Tcl_CmdProc*)test_io_trace },
{ "clang_sanitize_address", (Tcl_CmdProc*)clang_sanitize_address },
};
static struct {
char *zName;
+1 -1
View File
@@ -892,7 +892,7 @@ static int echoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
pIdxInfo->estimatedCost = cost;
}else if( useIdx ){
/* Approximation of log2(nRow). */
for( ii=0; ii<(sizeof(int)*8); ii++ ){
for( ii=0; ii<(sizeof(int)*8)-1; ii++ ){
if( nRow & (1<<ii) ){
pIdxInfo->estimatedCost = (double)ii;
}
+3 -2
View File
@@ -467,9 +467,10 @@ void sqlite3Update(
);
for(i=0; i<pTab->nCol; i++){
if( oldmask==0xffffffff
|| (i<32 && (oldmask & (1<<i)))
|| (i<32 && (oldmask & MASKBIT32(i))!=0)
|| (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
){
testcase( oldmask!=0xffffffff && i==31 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
@@ -504,7 +505,7 @@ void sqlite3Update(
j = aXRef[i];
if( j>=0 ){
sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
}else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
}else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
/* This branch loads the value of a column that will not be changed
** into a register. This is done if there are no BEFORE triggers, or
** if there are one or more BEFORE triggers that use this value via
+2 -1
View File
@@ -1001,7 +1001,8 @@ int sqlite3VarintLen(u64 v){
** Read or write a four-byte big-endian integer value.
*/
u32 sqlite3Get4byte(const u8 *p){
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
testcase( p[0]&0x80 );
return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
void sqlite3Put4byte(unsigned char *p, u32 v){
p[0] = (u8)(v>>24);
+1 -1
View File
@@ -6174,7 +6174,7 @@ case OP_Trace: {
if( zTrace ){
int i;
for(i=0; i<db->nDb; i++){
if( ((1<<i) & p->btreeMask)==0 ) continue;
if( MASKBIT(i) & p->btreeMask)==0 ) continue;
sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
}
}
+15 -11
View File
@@ -2615,8 +2615,9 @@ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
|| (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
|| (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
){
testcase( pAux->iArg==31 );
if( pAux->xDelete ){
pAux->xDelete(pAux->pAux);
}
@@ -2931,6 +2932,9 @@ u32 sqlite3VdbeSerialGet(
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
u64 x;
u32 y;
int i;
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
@@ -2944,23 +2948,26 @@ u32 sqlite3VdbeSerialGet(
return 1;
}
case 2: { /* 2-byte signed integer */
pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
i = 256*(signed char)buf[0] | buf[1];
pMem->u.i = (i64)i;
pMem->flags = MEM_Int;
return 2;
}
case 3: { /* 3-byte signed integer */
pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
i = 65536*(signed char)buf[0] | (buf[1]<<8) | buf[2];
pMem->u.i = (i64)i;
pMem->flags = MEM_Int;
return 3;
}
case 4: { /* 4-byte signed integer */
pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
pMem->u.i = (i64)*(int*)&y;
pMem->flags = MEM_Int;
return 4;
}
case 5: { /* 6-byte signed integer */
u64 x = (((signed char)buf[0])<<8) | buf[1];
u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
x = 256*(signed char)buf[0] + buf[1];
y = ((unsigned)buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
x = (x<<32) | y;
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
@@ -2968,8 +2975,6 @@ u32 sqlite3VdbeSerialGet(
}
case 6: /* 8-byte signed integer */
case 7: { /* IEEE floating point */
u64 x;
u32 y;
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Verify that integers and floating point values use the same
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
@@ -2982,9 +2987,8 @@ u32 sqlite3VdbeSerialGet(
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
x = ((unsigned)buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
y = ((unsigned)buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
x = (x<<32) | y;
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;
+1 -1
View File
@@ -598,7 +598,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
/*
** Size of struct Mem not including the Mem.zMalloc member.
*/
#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc))
#define MEMCELLSIZE offsetof(Mem,zMalloc)
/*
** Make an shallow copy of pFrom into pTo. Prior contents of
+24 -18
View File
@@ -179,16 +179,18 @@ do_test capi3-3.4 {
do_test capi3-3.5 {
sqlite3_close $db2
} {SQLITE_OK}
do_test capi3-3.6.1-misuse {
sqlite3_close $db2
} {SQLITE_MISUSE}
do_test capi3-3.6.2-misuse {
sqlite3_errmsg $db2
} {library routine called out of sequence}
ifcapable {utf16} {
do_test capi3-3.6.3-misuse {
utf8 [sqlite3_errmsg16 $db2]
if {[clang_sanitize_address]==0} {
do_test capi3-3.6.1-misuse {
sqlite3_close $db2
} {SQLITE_MISUSE}
do_test capi3-3.6.2-misuse {
sqlite3_errmsg $db2
} {library routine called out of sequence}
ifcapable {utf16} {
do_test capi3-3.6.3-misuse {
utf8 [sqlite3_errmsg16 $db2]
} {library routine called out of sequence}
}
}
do_test capi3-3.7 {
@@ -661,10 +663,12 @@ do_test capi3-6.3 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3-6.4-misuse {
db cache flush
sqlite3_close $DB
} {SQLITE_OK}
if {[clang_sanitize_address]==0} {
do_test capi3-6.4-misuse {
db cache flush
sqlite3_close $DB
} {SQLITE_OK}
}
db close
# This procedure sets the value of the file-format in file 'test.db'
@@ -1060,11 +1064,13 @@ if {[llength [info commands sqlite3_sleep]]>0} {
}
# Ticket #1219: Make sure binding APIs can handle a NULL pointer.
#
do_test capi3-14.1-misuse {
set rc [catch {sqlite3_bind_text 0 1 hello 5} msg]
lappend rc $msg
} {1 SQLITE_MISUSE}
#
if {[clang_sanitize_address]==0} {
do_test capi3-14.1-misuse {
set rc [catch {sqlite3_bind_text 0 1 hello 5} msg]
lappend rc $msg
} {1 SQLITE_MISUSE}
}
# Ticket #1650: Honor the nBytes parameter to sqlite3_prepare.
#
+21 -15
View File
@@ -169,16 +169,18 @@ do_test capi3c-3.4 {
do_test capi3c-3.5 {
sqlite3_close $db2
} {SQLITE_OK}
do_test capi3c-3.6.1-misuse {
sqlite3_close $db2
} {SQLITE_MISUSE}
do_test capi3c-3.6.2-misuse {
sqlite3_errmsg $db2
} {library routine called out of sequence}
ifcapable {utf16} {
do_test capi3c-3.6.3-misuse {
utf8 [sqlite3_errmsg16 $db2]
if {[clang_sanitize_address]==0} {
do_test capi3c-3.6.1-misuse {
sqlite3_close $db2
} {SQLITE_MISUSE}
do_test capi3c-3.6.2-misuse {
sqlite3_errmsg $db2
} {library routine called out of sequence}
ifcapable {utf16} {
do_test capi3c-3.6.3-misuse {
utf8 [sqlite3_errmsg16 $db2]
} {library routine called out of sequence}
}
}
# rename sqlite3_open ""
@@ -627,13 +629,17 @@ check_data $STMT capi3c-6.3 {INTEGER} {1} {1.0} {1}
do_test capi3c-6.3 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3c-6.4 {
db cache flush
sqlite3_close $DB
} {SQLITE_OK}
do_test capi3c-6.99-misuse {
if {[clang_sanitize_address]==0} {
do_test capi3c-6.4 {
db cache flush
sqlite3_close $DB
} {SQLITE_OK}
do_test capi3c-6.99-misuse {
db close
} {}
} else {
db close
} {}
}
# This procedure sets the value of the file-format in file 'test.db'
# to $newval. Also, the schema cookie is incremented.
+75 -25
View File
@@ -15,51 +15,68 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix closure01
ifcapable !vtab { finish_test ; return }
ifcapable !vtab||!cte { finish_test ; return }
load_static_extension db closure
do_execsql_test 1.0 {
BEGIN;
CREATE TABLE t1(x INTEGER PRIMARY KEY, y INTEGER);
WITH RECURSIVE
cnt(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM cnt LIMIT 131072)
INSERT INTO t1(x, y) SELECT i, nullif(i,1)/2 FROM cnt;
CREATE INDEX t1y ON t1(y);
INSERT INTO t1(x) VALUES(1),(2);
INSERT INTO t1(x) SELECT x+2 FROM t1;
INSERT INTO t1(x) SELECT x+4 FROM t1;
INSERT INTO t1(x) SELECT x+8 FROM t1;
INSERT INTO t1(x) SELECT x+16 FROM t1;
INSERT INTO t1(x) SELECT x+32 FROM t1;
INSERT INTO t1(x) SELECT x+64 FROM t1;
INSERT INTO t1(x) SELECT x+128 FROM t1;
INSERT INTO t1(x) SELECT x+256 FROM t1;
INSERT INTO t1(x) SELECT x+512 FROM t1;
INSERT INTO t1(x) SELECT x+1024 FROM t1;
INSERT INTO t1(x) SELECT x+2048 FROM t1;
INSERT INTO t1(x) SELECT x+4096 FROM t1;
INSERT INTO t1(x) SELECT x+8192 FROM t1;
INSERT INTO t1(x) SELECT x+16384 FROM t1;
INSERT INTO t1(x) SELECT x+32768 FROM t1;
INSERT INTO t1(x) SELECT x+65536 FROM t1;
UPDATE t1 SET y=x/2 WHERE x>1;
COMMIT;
CREATE VIRTUAL TABLE cx
USING transitive_closure(tablename=t1, idcolumn=x, parentcolumn=y);
} {}
# The entire table
do_execsql_test 1.1 {
do_timed_execsql_test 1.1 {
SELECT count(*), depth FROM cx WHERE root=1 GROUP BY depth ORDER BY 1;
} {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/}
do_timed_execsql_test 1.1-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(1,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below on t1.y=below.id
)
SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1;
} {/1 0 1 17 2 1 4 2 8 3 16 4 .* 65536 16/}
# descendents of 32768
do_execsql_test 1.2 {
do_timed_execsql_test 1.2 {
SELECT * FROM cx WHERE root=32768 ORDER BY id;
} {32768 0 65536 1 65537 1 131072 2}
do_timed_execsql_test 1.2-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(32768,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below on t1.y=below.id
WHERE below.depth<2
)
SELECT id, depth FROM below ORDER BY id;
} {32768 0 65536 1 65537 1 131072 2}
# descendents of 16384
do_execsql_test 1.3 {
do_timed_execsql_test 1.3 {
SELECT * FROM cx WHERE root=16384 AND depth<=2 ORDER BY id;
} {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2}
do_timed_execsql_test 1.3-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(16384,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below on t1.y=below.id
WHERE below.depth<2
)
SELECT id, depth FROM below ORDER BY id;
} {16384 0 32768 1 32769 1 65536 2 65537 2 65538 2 65539 2}
# children of 16384
do_execsql_test 1.4 {
@@ -70,19 +87,41 @@ do_execsql_test 1.4 {
} {32768 1 {} t1 x y 32769 1 {} t1 x y}
# great-grandparent of 16384
do_execsql_test 1.5 {
do_timed_execsql_test 1.5 {
SELECT id, depth, root, tablename, idcolumn, parentcolumn FROM cx
WHERE root=16384
AND depth=3
AND idcolumn='Y'
AND parentcolumn='X';
} {2048 3 {} t1 Y X}
do_timed_execsql_test 1.5-cte {
WITH RECURSIVE
above(id,depth) AS (
VALUES(16384,0)
UNION ALL
SELECT t1.y, above.depth+1
FROM t1 JOIN above ON t1.x=above.id
WHERE above.depth<3
)
SELECT id FROM above WHERE depth=3;
} {2048}
# depth<5
do_execsql_test 1.6 {
do_timed_execsql_test 1.6 {
SELECT count(*), depth FROM cx WHERE root=1 AND depth<5
GROUP BY depth ORDER BY 1;
} {1 0 2 1 4 2 8 3 16 4}
do_timed_execsql_test 1.6-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(1,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below ON t1.y=below.id
WHERE below.depth<4
)
SELECT count(*), depth FROM below GROUP BY depth ORDER BY 1;
} {1 0 2 1 4 2 8 3 16 4}
# depth<=5
do_execsql_test 1.7 {
@@ -103,9 +142,20 @@ do_execsql_test 1.9 {
} {8 3 16 4 32 5}
# depth==5 with min() and max()
do_execsql_test 1.10 {
do_timed_execsql_test 1.10 {
SELECT count(*), min(id), max(id) FROM cx WHERE root=1 AND depth=5;
} {32 32 63}
do_timed_execsql_test 1.10-cte {
WITH RECURSIVE
below(id,depth) AS (
VALUES(1,0)
UNION ALL
SELECT t1.x, below.depth+1
FROM t1 JOIN below ON t1.y=below.id
WHERE below.depth<5
)
SELECT count(*), min(id), max(id) FROM below WHERE depth=5;
} {32 32 63}
# Create a much smaller table t2 with only 32 elements
db eval {
+27 -1
View File
@@ -66,6 +66,7 @@ reset_db
# Initialize the database.
#
do_execsql_test 2.1 {
PRAGMA auto_vacuum=0;
PRAGMA page_size=1024;
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
@@ -95,8 +96,31 @@ do_test 2.2 {
sqlite3 db test.db
} {}
# The corruption migration caused by the test case below does not
# cause corruption to be detected in mmap mode.
#
# The trick here is that the root page of the tree scanned by the outer
# query is also currently on the free-list. So while the first seek on
# the table (for a==1) works, by the time the second is attempted The
# "INSERT INTO t2..." statements have recycled the root page of t1 and
# used it as an index leaf. Normally, BtreeMovetoUnpacked() detects
# that the PgHdr object associated with said root page does not match
# the cursor (as it is now marked with PgHdr.intKey==0) and returns
# SQLITE_CORRUPT.
#
# However, in mmap mode, the outer query and the inner queries use
# different PgHdr objects (same data, but different PgHdr container
# objects). And so the corruption is not detected. Instead, the second
# seek fails to find anything and only a single row is returned.
#
set res23 {1 {database disk image is malformed}}
if {[permutation]=="mmap"} {
set res23 {0 one}
}
do_test 2.3 {
list [catch {
set res [list]
db eval { SELECT * FROM t1 WHERE a IN (1, 2) } {
db eval {
INSERT INTO t2 SELECT randomblob(100) FROM t2;
@@ -105,9 +129,11 @@ do_test 2.3 {
INSERT INTO t2 SELECT randomblob(100) FROM t2;
INSERT INTO t2 SELECT randomblob(100) FROM t2;
}
lappend res $b
}
set res
} msg] $msg
} {1 {database disk image is malformed}}
} $res23
#-------------------------------------------------------------------------
reset_db
+39 -32
View File
@@ -2946,38 +2946,45 @@ proc test_on_update_recursion {limit} {
"
}
do_test e_fkey-63.1.1 {
test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH
} {0 0}
do_test e_fkey-63.1.2 {
test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.1.3 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
test_on_delete_recursion 5
} {0 0}
do_test e_fkey-63.1.4 {
test_on_delete_recursion 6
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.1.5 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
} {5}
do_test e_fkey-63.2.1 {
test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH
} {0 0}
do_test e_fkey-63.2.2 {
test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.2.3 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
test_on_update_recursion 5
} {0 0}
do_test e_fkey-63.2.4 {
test_on_update_recursion 6
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.2.5 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
} {5}
# If the current build was created using clang with the -fsanitize=address
# switch, then the library uses considerably more stack space than usual.
# So much more, that some of the following tests cause stack overflows
# if they are run under this configuration.
#
if {[clang_sanitize_address]==0} {
do_test e_fkey-63.1.1 {
test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH
} {0 0}
do_test e_fkey-63.1.2 {
test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.1.3 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
test_on_delete_recursion 5
} {0 0}
do_test e_fkey-63.1.4 {
test_on_delete_recursion 6
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.1.5 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
} {5}
do_test e_fkey-63.2.1 {
test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH
} {0 0}
do_test e_fkey-63.2.2 {
test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.2.3 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
test_on_update_recursion 5
} {0 0}
do_test e_fkey-63.2.4 {
test_on_update_recursion 6
} {1 {too many levels of trigger recursion}}
do_test e_fkey-63.2.5 {
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
} {5}
}
#-------------------------------------------------------------------------
# The setting of the recursive_triggers pragma does not affect foreign
+28 -30
View File
@@ -333,9 +333,9 @@ do_select_tests e_select-1.1 {
6 "SELECT count(*) WHERE 1" {1}
}
# EVIDENCE-OF: R-48114-33255 If there is only a single table in the
# join-source following the FROM clause, then the input data used by the
# SELECT statement is the contents of the named table.
# EVIDENCE-OF: R-45424-07352 If there is only a single table or subquery
# in the FROM clause, then the input data used by the SELECT statement
# is the contents of the named table.
#
# The results of the SELECT queries suggest that they are operating on the
# contents of the table 'xx'.
@@ -357,10 +357,10 @@ do_select_tests e_select-1.2 {
3 "SELECT sum(x), sum(y) FROM xx" {-17.89 -16.87}
}
# EVIDENCE-OF: R-23593-12456 If there is more than one table specified
# as part of the join-source following the FROM keyword, then the
# contents of each named table are joined into a single dataset for the
# simple SELECT statement to operate on.
# EVIDENCE-OF: R-28355-09804 If there is more than one table or subquery
# in FROM clause then the contents of all tables and/or subqueries are
# joined into a single dataset for the simple SELECT statement to
# operate on.
#
# There are more detailed tests for subsequent requirements that add
# more detail to this idea. We just add a single test that shows that
@@ -383,10 +383,10 @@ do_select_tests e_select-1.3 {
# of cartesian joins in the SELECT documentation is consistent with SQLite.
# In doing so, we test the following three requirements as a side-effect:
#
# EVIDENCE-OF: R-46122-14930 If the join-op is "CROSS JOIN", "INNER
# JOIN", "JOIN" or a comma (",") and there is no ON or USING clause,
# then the result of the join is simply the cartesian product of the
# left and right-hand datasets.
# EVIDENCE-OF: R-49872-03192 If the join-operator is "CROSS JOIN",
# "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING
# clause, then the result of the join is simply the cartesian product of
# the left and right-hand datasets.
#
# The tests are built on this assertion. Really, they test that the output
# of a CROSS JOIN, JOIN, INNER JOIN or "," join matches the expected result
@@ -513,11 +513,10 @@ do_select_tests e_select-1.4.5 [list \
4 { SELECT * FROM t1 AS y INNER JOIN t1 AS x } $t1_cross_t1 \
]
# EVIDENCE-OF: R-22775-56496 If there is an ON clause specified, then
# the ON expression is evaluated for each row of the cartesian product
# as a boolean expression. All rows for which the expression evaluates
# to false are excluded from the dataset.
# EVIDENCE-OF: R-38465-03616 If there is an ON clause then the ON
# expression is evaluated for each row of the cartesian product as a
# boolean expression. Only rows for which the expression evaluates to
# true are included from the dataset.
#
foreach {tn select res} [list \
1 { SELECT * FROM t1 %JOIN% t2 ON (1) } $t1_cross_t2 \
@@ -540,9 +539,9 @@ foreach {tn select res} [list \
do_join_test e_select-1.3.$tn $select $res
}
# EVIDENCE-OF: R-63358-54862 If there is a USING clause specified as
# part of the join-constraint, then each of the column names specified
# must exist in the datasets to both the left and right of the join-op.
# EVIDENCE-OF: R-49933-05137 If there is a USING clause then each of the
# column names specified must exist in the datasets to both the left and
# right of the join-operator.
#
do_select_tests e_select-1.4 -error {
cannot join using column %s - column not present in both tables
@@ -552,10 +551,10 @@ do_select_tests e_select-1.4 -error {
3 { SELECT * FROM t3, (SELECT a AS b, b AS c FROM t1) USING (a) } "a"
}
# EVIDENCE-OF: R-55987-04584 For each pair of namesake columns, the
# EVIDENCE-OF: R-22776-52830 For each pair of named columns, the
# expression "lhs.X = rhs.X" is evaluated for each row of the cartesian
# product as a boolean expression. All rows for which one or more of the
# expressions evaluates to false are excluded from the result set.
# product as a boolean expression. Only rows for which all such
# expressions evaluates to true are included from the result set.
#
do_select_tests e_select-1.5 {
1 { SELECT * FROM t1, t3 USING (a) } {a one 1 b two 2}
@@ -566,8 +565,8 @@ do_select_tests e_select-1.5 {
# USING clause, the normal rules for handling affinities, collation
# sequences and NULL values in comparisons apply.
#
# EVIDENCE-OF: R-35466-18578 The column from the dataset on the
# left-hand side of the join operator is considered to be on the
# EVIDENCE-OF: R-38422-04402 The column from the dataset on the
# left-hand side of the join-operator is considered to be on the
# left-hand side of the comparison operator (=) for the purposes of
# collation sequence and affinity precedence.
#
@@ -622,10 +621,9 @@ foreach {tn select res} {
} {
do_join_test e_select-1.7.$tn $select $res
}
# EVIDENCE-OF: R-41434-12448 If the join-op is a "LEFT JOIN" or "LEFT
# OUTER JOIN", then after the ON or USING filtering clauses have been
# applied, an extra row is added to the output for each row in the
# EVIDENCE-OF: R-42531-52874 If the join-operator is a "LEFT JOIN" or
# "LEFT OUTER JOIN", then after the ON or USING filtering clauses have
# been applied, an extra row is added to the output for each row in the
# original left-hand input dataset that corresponds to no rows at all in
# the composite dataset (if any).
#
@@ -660,8 +658,8 @@ do_select_tests e_select-1.9 {
2b "SELECT * FROM t7 LEFT JOIN t8 USING (a)" {x ex 24 abc 24 y why 25 {} {}}
}
# EVIDENCE-OF: R-01809-52134 If the NATURAL keyword is added to any of
# the join-ops, then an implicit USING clause is added to the
# EVIDENCE-OF: R-04932-55942 If the NATURAL keyword is in the
# join-operator then an implicit USING clause is added to the
# join-constraints. The implicit USING clause contains each of the
# column names that appear in both the left and right-hand input
# datasets.
+15 -15
View File
@@ -344,10 +344,10 @@ foreach {tn indexes} {
catchsql { DROP INDEX i3 }
execsql $indexes
# EVIDENCE-OF: R-46122-14930 If the join-op is "CROSS JOIN", "INNER
# JOIN", "JOIN" or a comma (",") and there is no ON or USING clause,
# then the result of the join is simply the cartesian product of the
# left and right-hand datasets.
# EVIDENCE-OF: R-49872-03192 If the join-operator is "CROSS JOIN",
# "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING
# clause, then the result of the join is simply the cartesian product of
# the left and right-hand datasets.
#
# EVIDENCE-OF: R-46256-57243 There is no difference between the "INNER
# JOIN", "JOIN" and "," join operators.
@@ -368,10 +368,10 @@ foreach {tn indexes} {
test_join $tn.1.11 "t2 CROSS JOIN t2 AS x" {t2 t2}
test_join $tn.1.12 "t2 JOIN t2 AS x" {t2 t2}
# EVIDENCE-OF: R-22775-56496 If there is an ON clause specified, then
# the ON expression is evaluated for each row of the cartesian product
# as a boolean expression. All rows for which the expression evaluates
# to false are excluded from the dataset.
# EVIDENCE-OF: R-38465-03616 If there is an ON clause then the ON
# expression is evaluated for each row of the cartesian product as a
# boolean expression. Only rows for which the expression evaluates to
# true are included from the dataset.
#
test_join $tn.2.1 "t1, t2 ON (t1.a=t2.a)" {t1 t2 -on {te_equals a a}}
test_join $tn.2.2 "t2, t1 ON (t1.a=t2.a)" {t2 t1 -on {te_equals a a}}
@@ -504,14 +504,14 @@ do_execsql_test e_select-2.2.0 {
INSERT INTO t5 VALUES(2, 'two');
} {}
# EVIDENCE-OF: R-55824-40976 A sub-select specified in the join-source
# following the FROM clause in a simple SELECT statement is handled as
# if it was a table containing the data returned by executing the
# sub-select statement.
# EVIDENCE-OF: R-59237-46742 A subquery specified in the
# table-or-subquery following the FROM clause in a simple SELECT
# statement is handled as if it was a table containing the data returned
# by executing the subquery statement.
#
# EVIDENCE-OF: R-42612-06757 Each column of the sub-select dataset
# inherits the collation sequence and affinity of the corresponding
# expression in the sub-select statement.
# EVIDENCE-OF: R-27438-53558 Each column of the subquery has the
# collation sequence and affinity of the corresponding expression in the
# subquery statement.
#
foreach {tn subselect select spec} {
1 "SELECT * FROM t2" "SELECT * FROM t1 JOIN %ss%"
+5 -3
View File
@@ -15,9 +15,11 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test misc7-1-misuse {
c_misuse_test
} {}
if {[clang_sanitize_address]==0} {
do_test misc7-1-misuse {
c_misuse_test
} {}
}
do_test misc7-2 {
c_realloc_test
+32 -29
View File
@@ -171,37 +171,40 @@ do_test misuse-4.3 {
} msg]
lappend v $msg $r
} {0 {} SQLITE_BUSY}
do_test misuse-4.4 {
if {[clang_sanitize_address]==0} {
do_test misuse-4.4 {
# Flush the TCL statement cache here, otherwise the sqlite3_close() will
# fail because there are still un-finalized() VDBEs.
db cache flush
sqlite3_close $::DB
catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}
do_test misuse-4.5 {
catchsql {
SELECT * FROM t1
}
} {1 {library routine called out of sequence}}
db cache flush
sqlite3_close $::DB
catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}
do_test misuse-4.5 {
catchsql {
SELECT * FROM t1
}
} {1 {library routine called out of sequence}}
# Attempt to use a database after it has been closed.
#
do_test misuse-5.1 {
db close
sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db]
execsql {
SELECT * FROM t1
}
} {1 2}
do_test misuse-5.2 {
catchsql2 {SELECT * FROM t1}
} {0 {a b 1 2}}
do_test misuse-5.3 {
db close
set r [catch {
sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL
} msg]
lappend r $msg
} {1 {(21) library routine called out of sequence}}
# Attempt to use a database after it has been closed.
#
do_test misuse-5.1 {
db close
sqlite3 db test2.db; set ::DB [sqlite3_connection_pointer db]
execsql {
SELECT * FROM t1
}
} {1 2}
do_test misuse-5.2 {
catchsql2 {SELECT * FROM t1}
} {0 {a b 1 2}}
do_test misuse-5.3 {
db close
set r [catch {
sqlite3_prepare $::DB {SELECT * FROM t1} -1 TAIL
} msg]
lappend r $msg
} {1 {(21) library routine called out of sequence}}
}
finish_test
+6 -1
View File
@@ -9,7 +9,7 @@
#
#***********************************************************************
#
# Tests for the SQLITE_IOERR_NODB error condition: the database file file
# Tests for the SQLITE_READONLY_DBMOVED error condition: the database file
# is unlinked or renamed out from under SQLite.
#
@@ -18,6 +18,11 @@ if {$tcl_platform(platform)!="unix"} return
set testdir [file dirname $argv0]
source $testdir/tester.tcl
if {[permutation]=="inmemory_journal"} {
finish_test
return
}
# Create a database file for testing
#
do_execsql_test pager4-1.1 {
+1
View File
@@ -1544,5 +1544,6 @@ do_faultsim_test pagerfault-36 -prep {
sqlite3_shutdown
sqlite3_config_uri 0
sqlite3_initialize
finish_test
+1 -1
View File
@@ -59,7 +59,7 @@ do_execsql_test printf2-1.11 {
SELECT printf('%lld%n',314159.2653,'hi');
} {314159}
# EVIDENCE-OF: R-20555-31089 The %z format is interchangable with %s.
# EVIDENCE-OF: R-17002-27534 The %z format is interchangeable with %s.
#
do_execsql_test printf2-1.12 {
SELECT printf('%.*z',5,'abcdefghijklmnop');
+16 -14
View File
@@ -138,21 +138,23 @@ ifcapable {subquery && compound} {
# Verify that an error occurs if you have too many terms on a
# compound select statement.
#
ifcapable compound {
if {$SQLITE_MAX_COMPOUND_SELECT>0} {
set sql {SELECT 0}
set result 0
for {set i 1} {$i<$SQLITE_MAX_COMPOUND_SELECT} {incr i} {
append sql " UNION ALL SELECT $i"
lappend result $i
if {[clang_sanitize_address]==0} {
ifcapable compound {
if {$SQLITE_MAX_COMPOUND_SELECT>0} {
set sql {SELECT 0}
set result 0
for {set i 1} {$i<$SQLITE_MAX_COMPOUND_SELECT} {incr i} {
append sql " UNION ALL SELECT $i"
lappend result $i
}
do_test select7-6.1 {
catchsql $sql
} [list 0 $result]
append sql { UNION ALL SELECT 99999999}
do_test select7-6.2 {
catchsql $sql
} {1 {too many terms in compound SELECT}}
}
do_test select7-6.1 {
catchsql $sql
} [list 0 $result]
append sql { UNION ALL SELECT 99999999}
do_test select7-6.2 {
catchsql $sql
} {1 {too many terms in compound SELECT}}
}
}
+47
View File
@@ -221,6 +221,53 @@ foreach {tn word res} {
} $res
}
#-------------------------------------------------------------------------
# Try some queries by rowid.
#
do_execsql_test 6.1.1 {
SELECT word FROM t3 WHERE rowid = 10;
} {keener}
do_execsql_test 6.1.2 {
SELECT word, distance FROM t3 WHERE rowid = 10;
} {keener {}}
do_execsql_test 6.1.3 {
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300}
ifcapable trace {
proc trace_callback {sql} {
if {[string range $sql 0 2] == "-- "} {
lappend ::trace [string range $sql 3 end]
}
}
proc do_tracesql_test {tn sql {res {}}} {
set ::trace [list]
uplevel [list do_test $tn [subst -nocommands {
set vals [execsql {$sql}]
concat [set vals] [set ::trace]
}] [list {*}$res]]
}
db trace trace_callback
do_tracesql_test 6.2.1 {
SELECT word FROM t3 WHERE rowid = 10;
} {keener
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.2 {
SELECT word, distance FROM t3 WHERE rowid = 10;
} {keener {}
{SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
}
do_tracesql_test 6.2.3 {
SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
} {keener 300
{SELECT id, word, rank, k1 FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
}
}
finish_test
+14
View File
@@ -59,6 +59,7 @@
# do_test TESTNAME SCRIPT EXPECTED
# do_execsql_test TESTNAME SQL EXPECTED
# do_catchsql_test TESTNAME SQL EXPECTED
# do_timed_execsql_test TESTNAME SQL EXPECTED
#
# Commands providing a lower level interface to the global test counters:
#
@@ -717,6 +718,11 @@ proc do_catchsql_test {testname sql result} {
fix_testname testname
uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result]
}
proc do_timed_execsql_test {testname sql {result {}}} {
fix_testname testname
uplevel do_test [list $testname] [list "execsql_timed {$sql}"]\
[list [list {*}$result]]
}
proc do_eqp_test {name sql res} {
uplevel do_execsql_test $name [list "EXPLAIN QUERY PLAN $sql"] [list $res]
}
@@ -1013,6 +1019,14 @@ proc execsql {sql {db db}} {
# puts "SQL = $sql"
uplevel [list $db eval $sql]
}
proc execsql_timed {sql {db db}} {
set tm [time {
set x [uplevel [list $db eval $sql]]
} 1]
set tm [lindex $tm 0]
puts -nonewline " ([expr {$tm*0.001}]ms) "
set x
}
# Execute SQL and catch exceptions.
#
+367 -2
View File
@@ -374,7 +374,7 @@ do_catchsql_test 7.6 {
# Compute the mandelbrot set using a recursive query
#
do_execsql_test 8.1 {
do_execsql_test 8.1-mandelbrot {
WITH RECURSIVE
xaxis(x) AS (VALUES(-2.0) UNION ALL SELECT x+0.05 FROM xaxis WHERE x<1.2),
yaxis(y) AS (VALUES(-1.0) UNION ALL SELECT y+0.1 FROM yaxis WHERE y<1.0),
@@ -417,7 +417,7 @@ do_execsql_test 8.1 {
# Solve a sudoku puzzle using a recursive query
#
do_execsql_test 8.2 {
do_execsql_test 8.2-soduko {
WITH RECURSIVE
input(sud) AS (
VALUES('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79')
@@ -452,4 +452,369 @@ do_execsql_test 8.2 {
SELECT s FROM x WHERE ind=0;
} {534678912672195348198342567859761423426853791713924856961537284287419635345286179}
#--------------------------------------------------------------------------
# Some tests that use LIMIT and OFFSET in the definition of recursive CTEs.
#
set I [list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
proc limit_test {tn iLimit iOffset} {
if {$iOffset < 0} { set iOffset 0 }
if {$iLimit < 0 } {
set result [lrange $::I $iOffset end]
} else {
set result [lrange $::I $iOffset [expr $iLimit+$iOffset-1]]
}
uplevel [list do_execsql_test $tn [subst -nocommands {
WITH ii(a) AS (
VALUES(1)
UNION ALL
SELECT a+1 FROM ii WHERE a<20
LIMIT $iLimit OFFSET $iOffset
)
SELECT * FROM ii
}] $result]
}
limit_test 9.1 20 0
limit_test 9.2 0 0
limit_test 9.3 19 1
limit_test 9.4 20 -1
limit_test 9.5 5 5
limit_test 9.6 0 -1
limit_test 9.7 40 -1
limit_test 9.8 -1 -1
limit_test 9.9 -1 -1
#--------------------------------------------------------------------------
# Test the ORDER BY clause on recursive tables.
#
do_execsql_test 10.1 {
DROP TABLE IF EXISTS tree;
CREATE TABLE tree(id INTEGER PRIMARY KEY, parentid, payload);
}
proc insert_into_tree {L} {
db eval { DELETE FROM tree }
foreach key $L {
unset -nocomplain parentid
foreach seg [split $key /] {
if {$seg==""} continue
set id [db one {
SELECT id FROM tree WHERE parentid IS $parentid AND payload=$seg
}]
if {$id==""} {
db eval { INSERT INTO tree VALUES(NULL, $parentid, $seg) }
set parentid [db last_insert_rowid]
} else {
set parentid $id
}
}
}
}
insert_into_tree {
/a/a/a
/a/b/c
/a/b/c/d
/a/b/d
}
do_execsql_test 10.2 {
WITH flat(fid, p) AS (
SELECT id, '/' || payload FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, p || '/' || payload FROM flat, tree WHERE parentid=fid
)
SELECT p FROM flat ORDER BY p;
} {
/a /a/a /a/a/a
/a/b /a/b/c /a/b/c/d
/a/b/d
}
# Scan the tree-structure currently stored in table tree. Return a list
# of nodes visited.
#
proc scan_tree {bDepthFirst bReverse} {
set order "ORDER BY "
if {$bDepthFirst==0} { append order "2 ASC," }
if {$bReverse==0} {
append order " 3 ASC"
} else {
append order " 3 DESC"
}
db eval "
WITH flat(fid, depth, p) AS (
SELECT id, 1, '/' || payload FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, p||'/'||payload FROM flat, tree WHERE parentid=fid
$order
)
SELECT p FROM flat;
"
}
insert_into_tree {
/a/b
/a/b/c
/a/d
/a/d/e
/a/d/f
/g/h
}
# Breadth first, siblings in ascending order.
#
do_test 10.3 {
scan_tree 0 0
} [list {*}{
/a /g
/a/b /a/d /g/h
/a/b/c /a/d/e /a/d/f
}]
# Depth first, siblings in ascending order.
#
do_test 10.4 {
scan_tree 1 0
} [list {*}{
/a /a/b /a/b/c
/a/d /a/d/e
/a/d/f
/g /g/h
}]
# Breadth first, siblings in descending order.
#
do_test 10.5 {
scan_tree 0 1
} [list {*}{
/g /a
/g/h /a/d /a/b
/a/d/f /a/d/e /a/b/c
}]
# Depth first, siblings in ascending order.
#
do_test 10.6 {
scan_tree 1 1
} [list {*}{
/g /g/h
/a /a/d /a/d/f
/a/d/e
/a/b /a/b/c
}]
# Test name resolution in ORDER BY clauses.
#
do_catchsql_test 10.7.1 {
WITH t(a) AS (
SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY a
)
SELECT * FROM t
} {1 {1st ORDER BY term does not match any column in the result set}}
do_execsql_test 10.7.2 {
WITH t(a) AS (
SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY b
)
SELECT * FROM t
} {1 2 3 4 5}
do_execsql_test 10.7.3 {
WITH t(a) AS (
SELECT 1 AS b UNION ALL SELECT a+1 AS c FROM t WHERE a<5 ORDER BY c
)
SELECT * FROM t
} {1 2 3 4 5}
# Test COLLATE clauses attached to ORDER BY.
#
insert_into_tree {
/a/b
/a/C
/a/d
/B/e
/B/F
/B/g
/c/h
/c/I
/c/j
}
do_execsql_test 10.8.1 {
WITH flat(fid, depth, p) AS (
SELECT id, 1, '/' || payload FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, p||'/'||payload FROM flat, tree WHERE parentid=fid
ORDER BY 2, 3 COLLATE nocase
)
SELECT p FROM flat;
} {
/a /B /c
/a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j
}
do_execsql_test 10.8.2 {
WITH flat(fid, depth, p) AS (
SELECT id, 1, ('/' || payload) COLLATE nocase
FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, (p||'/'||payload)
FROM flat, tree WHERE parentid=fid
ORDER BY 2, 3
)
SELECT p FROM flat;
} {
/a /B /c
/a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j
}
do_execsql_test 10.8.3 {
WITH flat(fid, depth, p) AS (
SELECT id, 1, ('/' || payload)
FROM tree WHERE parentid IS NULL
UNION ALL
SELECT id, depth+1, (p||'/'||payload) COLLATE nocase
FROM flat, tree WHERE parentid=fid
ORDER BY 2, 3
)
SELECT p FROM flat;
} {
/a /B /c
/a/b /a/C /a/d /B/e /B/F /B/g /c/h /c/I /c/j
}
do_execsql_test 10.8.4.1 {
CREATE TABLE tst(a,b);
INSERT INTO tst VALUES('a', 'A');
INSERT INTO tst VALUES('b', 'B');
INSERT INTO tst VALUES('c', 'C');
SELECT a COLLATE nocase FROM tst UNION ALL SELECT b FROM tst ORDER BY 1;
} {a A b B c C}
do_execsql_test 10.8.4.2 {
SELECT a FROM tst UNION ALL SELECT b COLLATE nocase FROM tst ORDER BY 1;
} {A B C a b c}
do_execsql_test 10.8.4.3 {
SELECT a||'' FROM tst UNION ALL SELECT b COLLATE nocase FROM tst ORDER BY 1;
} {a A b B c C}
# Test cases to illustrate on the ORDER BY clause on a recursive query can be
# used to control depth-first versus breath-first search in a tree.
#
do_execsql_test 11.1 {
CREATE TABLE org(
name TEXT PRIMARY KEY,
boss TEXT REFERENCES org
) WITHOUT ROWID;
INSERT INTO org VALUES('Alice',NULL);
INSERT INTO org VALUES('Bob','Alice');
INSERT INTO org VALUES('Cindy','Alice');
INSERT INTO org VALUES('Dave','Bob');
INSERT INTO org VALUES('Emma','Bob');
INSERT INTO org VALUES('Fred','Cindy');
INSERT INTO org VALUES('Gail','Cindy');
INSERT INTO org VALUES('Harry','Dave');
INSERT INTO org VALUES('Ingrid','Dave');
INSERT INTO org VALUES('Jim','Emma');
INSERT INTO org VALUES('Kate','Emma');
INSERT INTO org VALUES('Lanny','Fred');
INSERT INTO org VALUES('Mary','Fred');
INSERT INTO org VALUES('Noland','Gail');
INSERT INTO org VALUES('Olivia','Gail');
-- The above are all under Alice. Add a few more records for people
-- not in Alice's group, just to prove that they won't be selected.
INSERT INTO org VALUES('Xaviar',NULL);
INSERT INTO org VALUES('Xia','Xaviar');
INSERT INTO org VALUES('Xerxes','Xaviar');
INSERT INTO org VALUES('Xena','Xia');
-- Find all members of Alice's group, breath-first order
WITH RECURSIVE
under_alice(name,level) AS (
VALUES('Alice','0')
UNION ALL
SELECT org.name, under_alice.level+1
FROM org, under_alice
WHERE org.boss=under_alice.name
ORDER BY 2
)
SELECT group_concat(substr('...............',1,level*3) || name,x'0a')
FROM under_alice;
} {{Alice
...Bob
...Cindy
......Dave
......Emma
......Fred
......Gail
.........Harry
.........Ingrid
.........Jim
.........Kate
.........Lanny
.........Mary
.........Noland
.........Olivia}}
# The previous query used "ORDER BY level" to yield a breath-first search.
# Change that to "ORDER BY level DESC" for a depth-first search.
#
do_execsql_test 11.2 {
WITH RECURSIVE
under_alice(name,level) AS (
VALUES('Alice','0')
UNION ALL
SELECT org.name, under_alice.level+1
FROM org, under_alice
WHERE org.boss=under_alice.name
ORDER BY 2 DESC
)
SELECT group_concat(substr('...............',1,level*3) || name,x'0a')
FROM under_alice;
} {{Alice
...Bob
......Dave
.........Harry
.........Ingrid
......Emma
.........Jim
.........Kate
...Cindy
......Fred
.........Lanny
.........Mary
......Gail
.........Noland
.........Olivia}}
# Without an ORDER BY clause, the recursive query should use a FIFO,
# resulting in a breath-first search.
#
do_execsql_test 11.3 {
WITH RECURSIVE
under_alice(name,level) AS (
VALUES('Alice','0')
UNION ALL
SELECT org.name, under_alice.level+1
FROM org, under_alice
WHERE org.boss=under_alice.name
)
SELECT group_concat(substr('...............',1,level*3) || name,x'0a')
FROM under_alice;
} {{Alice
...Bob
...Cindy
......Dave
......Emma
......Fred
......Gail
.........Harry
.........Ingrid
.........Jim
.........Kate
.........Lanny
.........Mary
.........Noland
.........Olivia}}
finish_test
+1
View File
@@ -190,6 +190,7 @@ proc main {argv} {
SQLITE_OMIT_COMPILEOPTION_DIAGS \
SQLITE_OMIT_COMPLETE \
SQLITE_OMIT_COMPOUND_SELECT \
SQLITE_OMIT_CTE \
SQLITE_OMIT_DATETIME_FUNCS \
SQLITE_OMIT_DECLTYPE \
SQLITE_OMIT_DEPRECATED \
+5 -6
View File
@@ -119,7 +119,7 @@ static unsigned char *print_byte_range(
/*
** Print an entire page of content as hex
*/
static print_page(int iPg){
static void print_page(int iPg){
int iStart;
unsigned char *aData;
iStart = (iPg-1)*pagesize;
@@ -131,7 +131,7 @@ static print_page(int iPg){
/* Print a line of decode output showing a 4-byte integer.
*/
static print_decode_line(
static void print_decode_line(
unsigned char *aData, /* Content being decoded */
int ofst, int nByte, /* Start and size of decode */
const char *zMsg /* Message to append */
@@ -428,7 +428,7 @@ static void decode_trunk_page(
int detail, /* Show leaf pages if true */
int recursive /* Follow the trunk change if true */
){
int n, i, k;
int n, i;
unsigned char *a;
while( pgno>0 ){
a = getContent((pgno-1)*pagesize, pagesize);
@@ -495,7 +495,6 @@ static void page_usage_cell(
int cellno /* Index of the cell on the page */
){
int i;
int nDesc = 0;
int n = 0;
i64 nPayload;
i64 rowid;
@@ -677,7 +676,7 @@ static void page_usage_report(const char *zDbName){
if( rc==SQLITE_OK ){
while( sqlite3_step(pStmt)==SQLITE_ROW ){
int pgno = sqlite3_column_int(pStmt, 2);
page_usage_btree(pgno, 0, 0, sqlite3_column_text(pStmt, 1));
page_usage_btree(pgno, 0, 0, (const char*)sqlite3_column_text(pStmt,1));
}
}else{
printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db));
@@ -835,7 +834,6 @@ int main(int argc, char **argv){
free(a);
continue;
}else if( zLeft && zLeft[0]=='t' ){
unsigned char *a;
int detail = 0;
int recursive = 0;
int i;
@@ -861,4 +859,5 @@ int main(int argc, char **argv){
}
}
close(db);
return 0;
}