From 30c633a097241352a5232feb602bbfb330d7bcdf Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 5 Sep 2014 05:58:37 +0000 Subject: [PATCH 01/30] Fix harmless compiler warning. FossilOrigin-Name: 733119067757814609a9cea6b975818607bee4e3 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 58fd42dc62..8ae6336224 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scomments\sin\sthe\sANALYZE\scommand\sthat\sdescribe\show\sthe\sStat4Accum\nobjecct\sis\spassed\saround\swithin\sthe\sVDBE.\s\sNo\schanges\sto\sfunctional\scode. -D 2014-09-01T23:06:44.401 +C Fix\sharmless\scompiler\swarning. +D 2014-09-05T05:58:37.378 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -209,7 +209,7 @@ F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 8525ca79457c5b4673a5fda2774ee39fe155f40f -F src/os_win.c 2aa8aa7780d7cf03e912d2088ab2ec5c32f33dc5 +F src/os_win.c 3c9f7df710cb6c757b04b78bf3d98f03830e67b9 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/pager.c 3e732d2bbdd8d8d95fed0c5ae7e718d73153c4c5 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 @@ -1193,7 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4cae93f8ae8fb3fe38fd5dc7d3a5ea0d11552841 -R fe37d23fb1f96547febf2ff7c0ba49b9 -U drh -Z 29e2a2847ff584a00093c5b89ffca704 +P 9779c7a9eb1e2bd36e9286331a9314f064014d80 +R 05490459da8c4172c4abbda0933bfe68 +U mistachkin +Z b93a43f7e285c77b049b454cce5380d9 diff --git a/manifest.uuid b/manifest.uuid index af2604f469..fb28827b7e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9779c7a9eb1e2bd36e9286331a9314f064014d80 \ No newline at end of file +733119067757814609a9cea6b975818607bee4e3 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 46bf88e387..42d5106e5f 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1286,12 +1286,14 @@ void sqlite3_win32_sleep(DWORD milliseconds){ #endif } +#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINRT && SQLITE_THREADSAFE>0 DWORD sqlite3Win32Wait(HANDLE hObject){ DWORD rc; while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, TRUE))==WAIT_IO_COMPLETION ){} return rc; } +#endif /* ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP, From d8b77e20fc9bde3a55c1355705287cc23b203b95 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 6 Sep 2014 01:35:57 +0000 Subject: [PATCH 02/30] Query planner heuristic update: When doing a full table scan on a table that has an equality constraint on an unindexed column, do not allow the estimated number of output rows to be greater than half the total number of rows in the table. FossilOrigin-Name: 73954f93c4c6f880c6e01d0d130e3fed40fd4106 --- manifest | 18 +-- manifest.uuid | 2 +- src/sqliteInt.h | 1 - src/where.c | 34 ++++-- test/whereJ.test | 303 ++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 297 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index 8ae6336224..cf1f0a6433 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2014-09-05T05:58:37.378 +C Query\splanner\sheuristic\supdate:\nWhen\sdoing\sa\sfull\stable\sscan\son\sa\stable\sthat\shas\san\sequality\sconstraint\son\nan\sunindexed\scolumn,\sdo\snot\sallow\sthe\sestimated\snumber\sof\soutput\srows\sto\nbe\sgreater\sthan\shalf\sthe\stotal\snumber\sof\srows\sin\sthe\stable. +D 2014-09-06T01:35:57.122 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,7 +228,7 @@ F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50 F src/sqlite.h.in 43852c8b68b4c579948cb37182918078836c5c06 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 6244ee9052752e26d1275ab20c9b774385aa57d2 +F src/sqliteInt.h dbc9a4984a7e40f4334f8aefd3505f5aef4650a8 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -298,7 +298,7 @@ F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c d9eae96b2cbbe4842eac3ee156ccd1b933d802c4 +F src/where.c 738213f25bc74c0a7cc5427712c1ac7537270a3d F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1125,7 +1125,7 @@ F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 -F test/whereJ.test 8880784c211c459595f734a35bcc5f2061fce987 +F test/whereJ.test 1c35169106be343b7aa1a2c1338322462f27901a F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1193,7 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9779c7a9eb1e2bd36e9286331a9314f064014d80 -R 05490459da8c4172c4abbda0933bfe68 -U mistachkin -Z b93a43f7e285c77b049b454cce5380d9 +P 733119067757814609a9cea6b975818607bee4e3 +R bfd7d8b21e261616a30a072bf666f263 +U drh +Z 6641f77f6592cd795a1a1b9c2011a8f5 diff --git a/manifest.uuid b/manifest.uuid index fb28827b7e..a84ea01b2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -733119067757814609a9cea6b975818607bee4e3 \ No newline at end of file +73954f93c4c6f880c6e01d0d130e3fed40fd4106 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7fd999d9ee..e56da4edd0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1159,7 +1159,6 @@ struct sqlite3 { #define SQLITE_Transitive 0x0200 /* Transitive constraints */ #define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ #define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */ -#define SQLITE_AdjustOutEst 0x1000 /* Adjust output estimates using WHERE */ #define SQLITE_AllOpts 0xffff /* All optimizations */ /* diff --git a/src/where.c b/src/where.c index e1e1e1d528..49b16b345d 100644 --- a/src/where.c +++ b/src/where.c @@ -4221,14 +4221,16 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** the number of output rows by a factor of 10 and each additional term ** reduces the number of output rows by sqrt(2). */ -static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop){ +static void whereLoopOutputAdjust( + WhereClause *pWC, /* The WHERE clause */ + WhereLoop *pLoop, /* The loop to adjust downward */ + LogEst nRow /* Number of rows in the entire table */ +){ WhereTerm *pTerm, *pX; Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); int i, j; + int nEq = 0; /* Number of = constraints not within likely()/unlike() */ - if( !OptimizationEnabled(pWC->pWInfo->pParse->db, SQLITE_AdjustOutEst) ){ - return; - } for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; @@ -4240,9 +4242,21 @@ static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop){ if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; } if( j<0 ){ - pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1); + if( pTerm->truthProb<=0 ){ + pLoop->nOut += pTerm->truthProb; + }else{ + pLoop->nOut--; + if( pTerm->eOperator&WO_EQ ) nEq++; + } } } + /* TUNING: If there is at least one equality constraint in the WHERE + ** clause that does not have a likelihood() explicitly assigned to it + ** then do not let the estimated number of output rows exceed half + ** the number of rows in the table. */ + if( nEq && pLoop->nOut>nRow-10 ){ + pLoop->nOut = nRow - 10; + } } /* @@ -4288,6 +4302,7 @@ static int whereLoopAddBtreeIndex( LogEst saved_nOut; /* Original value of pNew->nOut */ int iCol; /* Index of the column in the table */ int rc = SQLITE_OK; /* Return code */ + LogEst rSize; /* Number of rows in the table */ LogEst rLogSize; /* Logarithm of table size */ WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ @@ -4317,7 +4332,8 @@ static int whereLoopAddBtreeIndex( saved_prereq = pNew->prereq; saved_nOut = pNew->nOut; pNew->rSetup = 0; - rLogSize = estLog(pProbe->aiRowLogEst[0]); + rSize = pProbe->aiRowLogEst[0]; + rLogSize = estLog(rSize); /* Consider using a skip-scan if there are no WHERE clause constraints ** available for the left-most terms of the index, and if the average @@ -4494,7 +4510,7 @@ static int whereLoopAddBtreeIndex( nOutUnadjusted = pNew->nOut; pNew->rRun += nInMul + nIn; pNew->nOut += nInMul + nIn; - whereLoopOutputAdjust(pBuilder->pWC, pNew); + whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ @@ -4748,7 +4764,7 @@ static int whereLoopAddBtree( /* TUNING: Cost of full table scan is (N*3.0). */ pNew->rRun = rSize + 16; ApplyCostMultiplier(pNew->rRun, pTab->costMult); - whereLoopOutputAdjust(pWC, pNew); + whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; @@ -4784,7 +4800,7 @@ static int whereLoopAddBtree( pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16); } ApplyCostMultiplier(pNew->rRun, pTab->costMult); - whereLoopOutputAdjust(pWC, pNew); + whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); pNew->nOut = rSize; if( rc ) break; diff --git a/test/whereJ.test b/test/whereJ.test index 7c37321cbf..fbc2e57a3f 100644 --- a/test/whereJ.test +++ b/test/whereJ.test @@ -373,50 +373,271 @@ do_execsql_test whereJ-2.2 { ############################################################################ -ifcapable stat4 { - # Create and populate table. - do_execsql_test 3.1 { CREATE TABLE t1(a, b, c) } - for {set i 0} {$i < 32} {incr i 2} { - for {set x 0} {$x < 100} {incr x} { - execsql { INSERT INTO t1 VALUES($i, $x, $c) } - incr c - } - execsql { INSERT INTO t1 VALUES($i+1, 5, $c) } +# Create and populate table. +do_execsql_test 3.1 { CREATE TABLE t1(a, b, c) } +for {set i 0} {$i < 32} {incr i 2} { + for {set x 0} {$x < 100} {incr x} { + execsql { INSERT INTO t1 VALUES($i, $x, $c) } incr c } - - do_execsql_test 3.2 { - SELECT a, count(*) FROM t1 GROUP BY a HAVING a < 8; - } { - 0 100 1 1 2 100 3 1 4 100 5 1 6 100 7 1 - } - - do_execsql_test 3.3 { - CREATE INDEX idx_ab ON t1(a, b); - CREATE INDEX idx_c ON t1(c); - ANALYZE; - } {} - - # This one should use index "idx_c". - do_eqp_test 3.4 { - SELECT * FROM t1 WHERE - a = 4 AND b BETWEEN 20 AND 80 -- Matches 80 rows - AND - c BETWEEN 150 AND 160 -- Matches 10 rows - } { - 0 0 0 {SEARCH TABLE t1 USING INDEX idx_c (c>? AND c? AND b? AND c? AND b Date: Sat, 6 Sep 2014 02:00:41 +0000 Subject: [PATCH 03/30] Fix a couple of typos in comments. No changes to code. FossilOrigin-Name: a758465e3cfa7e0cb8749d097cd6fb5f86b60955 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 2 +- test/whereJ.test | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index cf1f0a6433..8921cbf2bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Query\splanner\sheuristic\supdate:\nWhen\sdoing\sa\sfull\stable\sscan\son\sa\stable\sthat\shas\san\sequality\sconstraint\son\nan\sunindexed\scolumn,\sdo\snot\sallow\sthe\sestimated\snumber\sof\soutput\srows\sto\nbe\sgreater\sthan\shalf\sthe\stotal\snumber\sof\srows\sin\sthe\stable. -D 2014-09-06T01:35:57.122 +C Fix\sa\scouple\sof\stypos\sin\scomments.\s\sNo\schanges\sto\scode. +D 2014-09-06T02:00:41.865 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -298,7 +298,7 @@ F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 738213f25bc74c0a7cc5427712c1ac7537270a3d +F src/where.c 27af96780ded74196df231849b0584db5dc67104 F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1125,7 +1125,7 @@ F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test 69f5ec4b15760a8c860f80e2d55525669390aab3 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 -F test/whereJ.test 1c35169106be343b7aa1a2c1338322462f27901a +F test/whereJ.test 63599653dfefe4e74ebb358db753417fe0aa8a49 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1193,7 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 733119067757814609a9cea6b975818607bee4e3 -R bfd7d8b21e261616a30a072bf666f263 -U drh -Z 6641f77f6592cd795a1a1b9c2011a8f5 +P 73954f93c4c6f880c6e01d0d130e3fed40fd4106 +R fbb4555bc7385b94054e7551d7f50581 +U mistachkin +Z 680a54f7aef088a3bc667976a8b39ee7 diff --git a/manifest.uuid b/manifest.uuid index a84ea01b2d..08d7f777bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -73954f93c4c6f880c6e01d0d130e3fed40fd4106 \ No newline at end of file +a758465e3cfa7e0cb8749d097cd6fb5f86b60955 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 49b16b345d..921baa29eb 100644 --- a/src/where.c +++ b/src/where.c @@ -4229,7 +4229,7 @@ static void whereLoopOutputAdjust( WhereTerm *pTerm, *pX; Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); int i, j; - int nEq = 0; /* Number of = constraints not within likely()/unlike() */ + int nEq = 0; /* Number of = constraints not within likely()/unlikely() */ for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; diff --git a/test/whereJ.test b/test/whereJ.test index fbc2e57a3f..8431c3a4b0 100644 --- a/test/whereJ.test +++ b/test/whereJ.test @@ -418,7 +418,7 @@ do_eqp_test 3.5 { ########################################################################################### -# Reset the database and setup for a test case derived from an actual SQLite users +# Reset the database and setup for a test case derived from actual SQLite users # db close sqlite3 db test.db @@ -618,7 +618,7 @@ do_execsql_test 4.2 { ANALYZE sqlite_master; } {} -# The following query should do a ful ltable scan of cx in the outer loop. +# The following query should do a full table scan of cx in the outer loop. # It is not correct to search table px using indx p_pt in the outer loop # with cx in the middle loop. Test case from Bloomberg on 2014-09-05. # From 44ee1dc84393aaae0cf82f741eab77a7a1f11668 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 6 Sep 2014 03:16:28 +0000 Subject: [PATCH 04/30] Add the sqlite3_memdebug_title_count global variable, used during debugging to count the number of invocations of test_memdebug_settitle. By examining this variable in the debugger after a segfault, one can then set a breakpoint on test_memdebug_settitle that will fire just before the problem. FossilOrigin-Name: 27e3ca3e0f1da54e3527704a8601bb9003b086bf --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_malloc.c | 7 +++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8921cbf2bc..2916276efe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sof\stypos\sin\scomments.\s\sNo\schanges\sto\scode. -D 2014-09-06T02:00:41.865 +C Add\sthe\ssqlite3_memdebug_title_count\sglobal\svariable,\sused\sduring\sdebugging\nto\scount\sthe\snumber\sof\sinvocations\sof\stest_memdebug_settitle.\s\sBy\sexamining\nthis\svariable\sin\sthe\sdebugger\safter\sa\ssegfault,\sone\scan\sthen\sset\sa\sbreakpoint\non\stest_memdebug_settitle\sthat\swill\sfire\sjust\sbefore\sthe\sproblem. +D 2014-09-06T03:16:28.654 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -257,7 +257,7 @@ F src/test_intarray.c db4614c2262a06abc4409dc048d59c580c38320f F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4 -F src/test_malloc.c 5368fb1de77246da1ae0ff59cba0d30cb0e5812f +F src/test_malloc.c fdac9732bd5ad6ae21d6b36cc265cca467caefb1 F src/test_multiplex.c ca90057438b63bf0840ebb84d0ef050624519a76 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f @@ -1193,7 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 73954f93c4c6f880c6e01d0d130e3fed40fd4106 -R fbb4555bc7385b94054e7551d7f50581 -U mistachkin -Z 680a54f7aef088a3bc667976a8b39ee7 +P a758465e3cfa7e0cb8749d097cd6fb5f86b60955 +R 2db0351830e46d232702315b1a375c8e +U drh +Z b61df9da0225ca7d80ceab8d31d99aad diff --git a/manifest.uuid b/manifest.uuid index 08d7f777bc..48a730b1f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a758465e3cfa7e0cb8749d097cd6fb5f86b60955 \ No newline at end of file +27e3ca3e0f1da54e3527704a8601bb9003b086bf \ No newline at end of file diff --git a/src/test_malloc.c b/src/test_malloc.c index 900a8ac40c..b937cea7cf 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -696,6 +696,12 @@ static int test_memdebug_pending( return TCL_OK; } +/* +** The following global variable keeps track of the number of tests +** that have run. This variable is only useful when running in the +** debugger. +*/ +static int sqlite3_memdebug_title_count = 0; /* ** Usage: sqlite3_memdebug_settitle TITLE @@ -713,6 +719,7 @@ static int test_memdebug_settitle( int objc, Tcl_Obj *CONST objv[] ){ + sqlite3_memdebug_title_count++; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "TITLE"); return TCL_ERROR; From 60da72741ab642bd590480a397dead6a581000d3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 6 Sep 2014 03:38:51 +0000 Subject: [PATCH 05/30] Do not require a page-size change if the attempt to change the page size failed due to an OOM error. FossilOrigin-Name: 4d4fb197dc438a486cf5d967cf435f1132902c63 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2916276efe..166446fe6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_memdebug_title_count\sglobal\svariable,\sused\sduring\sdebugging\nto\scount\sthe\snumber\sof\sinvocations\sof\stest_memdebug_settitle.\s\sBy\sexamining\nthis\svariable\sin\sthe\sdebugger\safter\sa\ssegfault,\sone\scan\sthen\sset\sa\sbreakpoint\non\stest_memdebug_settitle\sthat\swill\sfire\sjust\sbefore\sthe\sproblem. -D 2014-09-06T03:16:28.654 +C Do\snot\srequire\sa\spage-size\schange\sif\sthe\sattempt\sto\schange\sthe\spage\ssize\nfailed\sdue\sto\san\sOOM\serror. +D 2014-09-06T03:38:51.792 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -211,7 +211,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 8525ca79457c5b4673a5fda2774ee39fe155f40f F src/os_win.c 3c9f7df710cb6c757b04b78bf3d98f03830e67b9 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 -F src/pager.c 3e732d2bbdd8d8d95fed0c5ae7e718d73153c4c5 +F src/pager.c a5e1a498696c96799a84b1c0c7dcd8c6dda80620 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c 3b3791297e8977002e56b4a9b8916f2039abad9b @@ -1193,7 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a758465e3cfa7e0cb8749d097cd6fb5f86b60955 -R 2db0351830e46d232702315b1a375c8e +P 27e3ca3e0f1da54e3527704a8601bb9003b086bf +R 3c6eecd4803891788e881a3031c570ff U drh -Z b61df9da0225ca7d80ceab8d31d99aad +Z b558ffb0132cb5c0f9f09b23281337a0 diff --git a/manifest.uuid b/manifest.uuid index 48a730b1f6..29e9f91571 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27e3ca3e0f1da54e3527704a8601bb9003b086bf \ No newline at end of file +4d4fb197dc438a486cf5d967cf435f1132902c63 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 3ef54d98e0..681968e3cd 100644 --- a/src/pager.c +++ b/src/pager.c @@ -3618,12 +3618,14 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ if( rc==SQLITE_OK ){ pager_reset(pPager); - pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); - pPager->pageSize = pageSize; sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); } + if( rc==SQLITE_OK ){ + pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); + pPager->pageSize = pageSize; + } } *pPageSize = pPager->pageSize; From 60ec914c74ec79e4b73c004d1c21330be7916c99 Mon Sep 17 00:00:00 2001 From: "peter.d.reid" Date: Sat, 6 Sep 2014 16:39:46 +0000 Subject: [PATCH 06/30] Fix typos in comments. No code changes. FossilOrigin-Name: e62aab5e9290503869e1f4d5e0fefd2b4dee0a69 --- manifest | 122 ++++++++++++++++++++++---------------------- manifest.uuid | 2 +- src/alter.c | 4 +- src/analyze.c | 6 +-- src/btmutex.c | 2 +- src/btree.c | 30 +++++------ src/btreeInt.h | 6 +-- src/build.c | 10 ++-- src/callback.c | 2 +- src/complete.c | 6 +-- src/date.c | 2 +- src/delete.c | 10 ++-- src/expr.c | 22 ++++---- src/fkey.c | 2 +- src/func.c | 4 +- src/global.c | 2 +- src/insert.c | 14 ++--- src/main.c | 6 +-- src/mem1.c | 2 +- src/mem5.c | 2 +- src/memjournal.c | 2 +- src/mutex.h | 2 +- src/os.h | 2 +- src/os_unix.c | 20 ++++---- src/os_win.c | 4 +- src/pager.c | 20 ++++---- src/pcache.c | 2 +- src/pcache1.c | 4 +- src/printf.c | 2 +- src/resolve.c | 2 +- src/rowset.c | 6 +-- src/select.c | 16 +++--- src/sqlite.h.in | 10 ++-- src/sqlite3ext.h | 4 +- src/sqliteInt.h | 8 +-- src/table.c | 2 +- src/tclsqlite.c | 2 +- src/test1.c | 4 +- src/test_intarray.c | 4 +- src/test_malloc.c | 4 +- src/test_schema.c | 2 +- src/tokenize.c | 2 +- src/trigger.c | 2 +- src/update.c | 10 ++-- src/util.c | 2 +- src/vacuum.c | 2 +- src/vdbe.c | 4 +- src/vdbeInt.h | 4 +- src/vdbeapi.c | 16 +++--- src/vdbeaux.c | 18 +++---- src/vdbemem.c | 8 +-- src/vdbesort.c | 2 +- src/vdbetrace.c | 2 +- src/wal.c | 12 ++--- src/walker.c | 2 +- src/where.c | 18 +++---- src/whereInt.h | 2 +- 57 files changed, 242 insertions(+), 242 deletions(-) diff --git a/manifest b/manifest index 166446fe6b..bfce404357 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\srequire\sa\spage-size\schange\sif\sthe\sattempt\sto\schange\sthe\spage\ssize\nfailed\sdue\sto\san\sOOM\serror. -D 2014-09-06T03:38:51.792 +C Fix\stypos\sin\scomments.\sNo\scode\schanges. +D 2014-09-06T16:39:46.963 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,79 +161,79 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 -F src/analyze.c f00f06e6ef66c61b41f154889fe7caf5ed55a0ce +F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb +F src/analyze.c 79383a54fee3b7f1fb03dd4c8c8115583f506de5 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb -F src/btmutex.c ec9d3f1295dafeb278c3830211cc5584132468f4 -F src/btree.c 2a483a8045118faa99867a8679da42754b532318 +F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 +F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 -F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 -F src/build.c c26b233dcdb1e2c8f468d49236c266f9f3de96d8 -F src/callback.c b97d0695ffcf6a8710ee445ffe56ee387d4d8a6f -F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac +F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc +F src/build.c 8cb237719c185eec7bd8449b2e747491ded11932 +F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 +F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a -F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 5adcd322c6b08fc25d215d780ca62cebce66304d -F src/expr.c e1691ab0fe6be7247ef073b0038fb8ecd9944fad +F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036 +F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f +F src/expr.c 441a7e24e2f7bea9475778fa8acce9e8a69ca8f0 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 8d81a780ad78d16ec9082585758a8f1d6bf02ca3 -F src/func.c bbb724b74ed96ca42675a7274646a71dd52bcda7 -F src/global.c 1e4bd956dc2f608f87d2a929abc4a20db65f30e4 +F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 +F src/func.c 0517037766e18eff7dce298e6b3a8e6311df75ec +F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c d1a104e67b33314d4cc5c1356147446086ab9fc8 +F src/insert.c 0b073fade178d9dbd990bbb32b4438e50b884a06 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 31c2122b7dd05a179049bbf163fd4839f181cbab -F src/main.c d2ef03a45552e11813c68326d5edfda992e319d4 +F src/main.c e48517e3da289d93ad86e8b7b4f68078df5e6e51 F src/malloc.c 954de5f998c23237e04474a3f2159bf483bba65a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b +F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 -F src/mem5.c 74670012946c4adc8a6ad84d03acc80959c3e529 -F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785 +F src/mem5.c 61eeb90134f9a5be6c2e68d8daae7628b25953fb +F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85 F src/mutex.c 84a073c9a23a8d7bdd2ea832522d1730df18812c -F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea +F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c f3f09fd7a2eb4287cfc799753ffc30380e7b71a1 F src/mutex_unix.c 1b10d5413dfc794364a8adf3eb3a192926b43fa3 F src/mutex_w32.c 06bfff9a3a83b53389a51a967643db3967032e1e F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace -F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e +F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 8525ca79457c5b4673a5fda2774ee39fe155f40f -F src/os_win.c 3c9f7df710cb6c757b04b78bf3d98f03830e67b9 +F src/os_unix.c 576f95b5b02397044ebbcdc1027528ba1bb2d92e +F src/os_win.c 0a4042ef35f322e86fa01f6c8884c5e645b911e7 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 -F src/pager.c a5e1a498696c96799a84b1c0c7dcd8c6dda80620 +F src/pager.c 31da9594ad4c3b5851bb6fe1a95c33835ab7ddce F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 -F src/pcache.c 3b3791297e8977002e56b4a9b8916f2039abad9b +F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a -F src/pcache1.c c5af6403a55178c9d1c09e4f77b0f9c88822762c +F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 14bcdb504128a476cce5bbc086d5226c5e46c225 F src/prepare.c 3842c1dfc0b053458e3adcf9f6efc48e03e3fe3d -F src/printf.c 00986c86ddfffefc2fd3c73667ff51b3b9709c74 +F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece -F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697 -F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be -F src/select.c 89e569b263535662f54b537eb9118b2c554ae7aa +F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb +F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e +F src/select.c b4457526cee73c0b69fad42f799f619b1d5a8a8a F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50 -F src/sqlite.h.in 43852c8b68b4c579948cb37182918078836c5c06 +F src/sqlite.h.in 64a77f2822f1325b12050972003184f99b655a0f F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad -F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h dbc9a4984a7e40f4334f8aefd3505f5aef4650a8 +F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4 +F src/sqliteInt.h 4d1b0488f097aa7be346176c4d5e3cc1e25d99da F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 -F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 7d100e2e7aad614bb3d7026a41a0e3827dbaaebc -F src/test1.c 363a5089230a92cf0aaa7a2945da7f2bf3b0a8d3 +F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08 +F src/tclsqlite.c 8d6d6833c0053f0b3b1aeb1c5c7a7eeff0ad4d3f +F src/test1.c 22bfe1ce9f2f3746d682093a475ec0a33e0e55d8 F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df @@ -253,11 +253,11 @@ F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f F src/test_func.c d3013ce36f19ac72a99c73864930fd1fa41832f8 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 -F src/test_intarray.c db4614c2262a06abc4409dc048d59c580c38320f +F src/test_intarray.c 6c610a21ab8edde85a3a2c7f2b069244ecf4d834 F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4 -F src/test_malloc.c fdac9732bd5ad6ae21d6b36cc265cca467caefb1 +F src/test_malloc.c ba34143f941a9d74b30bbffc8818389bb73a1ca2 F src/test_multiplex.c ca90057438b63bf0840ebb84d0ef050624519a76 F src/test_multiplex.h c08e4e8f8651f0c5e0509b138ff4d5b43ed1f5d3 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f @@ -267,7 +267,7 @@ F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_quota.c 65f6348fec0f2b3020c907247fb47556b214abb9 F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d F src/test_rtree.c fdd8d29ca5165c7857987a2ba263fac5c69e231f -F src/test_schema.c cd12a2223c3a394f4d07bb93bdf6d344c5c121b6 +F src/test_schema.c 2bdba21b82f601da69793e1f1d11bf481a79b091 F src/test_server.c a2615049954cbb9cfb4a62e18e2f0616e4dc38fe F src/test_sqllog.c c1c1bbedbcaf82b93d83e4f9dd990e62476a680e F src/test_stat.c 9898687a6c2beca733b0dd6fe19163d987826d31 @@ -279,27 +279,27 @@ F src/test_vfs.c f84075a388527892ff184988f43b69ce69b8083c F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 22dded4283dc4b25422f6444cdcb8d6b1ea0b5ff -F src/tokenize.c ae45399d6252b4d736af43bee1576ce7bff86aec -F src/trigger.c 4bddd12803275aa98f1c7ce0118fceb02b2167f6 -F src/update.c ea336ce7b8b3fc5e316ba8f082e6445babf81059 +F src/tokenize.c 722872c816887fd66931333c59570ebd9622a95f +F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f +F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359 -F src/util.c 068dcd26354a3898ccc64ad5c4bdb95a7a15d33a -F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 90db7ad740b6d3f7ab446e6244dbc17ce495cca6 +F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 +F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a +F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 -F src/vdbeInt.h cdc8e421f85beb1ac9b4669ec5beadab6faa15e0 -F src/vdbeapi.c 09677a53dd8c71bcd670b0bd073bb9aefa02b441 -F src/vdbeaux.c cef5d34a64ae3a65b56d96d3fd663246ec8e1c36 +F src/vdbeInt.h b4843c35c3ba533b69d4250f550b5bacf2fb013d +F src/vdbeapi.c e43a6b98f853d8064cc096e349ce47e63d4c72d2 +F src/vdbeaux.c 91fd1e0c54a765838dc61fcf79f31acce035ce38 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 921d5468a68ac06f369810992e84ca22cc730a62 -F src/vdbesort.c 02646a9f86421776ae5d7594f620f9ed669d3698 -F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767 +F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a +F src/vdbesort.c ab39574ec6e0c6213bd2a5c09cca9f9f8ba98450 +F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f -F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a +F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 -F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 27af96780ded74196df231849b0584db5dc67104 -F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3 +F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 +F src/where.c 839b5e1db2507e221ad1c308f148a8519ed750be +F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 @@ -1193,7 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 27e3ca3e0f1da54e3527704a8601bb9003b086bf -R 3c6eecd4803891788e881a3031c570ff -U drh -Z b558ffb0132cb5c0f9f09b23281337a0 +P 4d4fb197dc438a486cf5d967cf435f1132902c63 +R db0dce11ff1f08f3ef74aeb9c5ce2829 +U peter.d.reid +Z 050bcae7bdbaf9a55cc282a84c1e1741 diff --git a/manifest.uuid b/manifest.uuid index 29e9f91571..3f8f17bbce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d4fb197dc438a486cf5d967cf435f1132902c63 \ No newline at end of file +e62aab5e9290503869e1f4d5e0fefd2b4dee0a69 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 64204b7b24..dd060248b8 100644 --- a/src/alter.c +++ b/src/alter.c @@ -174,8 +174,8 @@ static void renameTriggerFunc( UNUSED_PARAMETER(NotUsed); /* The principle used to locate the table name in the CREATE TRIGGER - ** statement is that the table name is the first token that is immediatedly - ** preceded by either TK_ON or TK_DOT and immediatedly followed by one + ** statement is that the table name is the first token that is immediately + ** preceded by either TK_ON or TK_DOT and immediately followed by one ** of TK_WHEN, TK_BEGIN or TK_FOR. */ if( zSql ){ diff --git a/src/analyze.c b/src/analyze.c index 9920c32a80..d5a11a3ed6 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -35,7 +35,7 @@ ** not possible to enable both STAT3 and STAT4 at the same time. If they ** are both enabled, then STAT4 takes precedence. ** -** For most applications, sqlite_stat1 provides all the statisics required +** For most applications, sqlite_stat1 provides all the statistics required ** for the query planner to make good choices. ** ** Format of sqlite_stat1: @@ -387,7 +387,7 @@ static void stat4Destructor(void *pOld){ ** original WITHOUT ROWID table as N==K as a special case. ** ** This routine allocates the Stat4Accum object in heap memory. The return -** value is a pointer to the the Stat4Accum object. The datatype of the +** value is a pointer to the Stat4Accum object. The datatype of the ** return value is BLOB, but it is really just a pointer to the Stat4Accum ** object. */ @@ -1583,7 +1583,7 @@ static void initAvgEq(Index *pIdx){ /* Set nSum to the number of distinct (iCol+1) field prefixes that ** occur in the stat4 table for this index before pFinal. Set ** sumEq to the sum of the nEq values for column iCol for the same - ** set (adding the value only once where there exist dupicate + ** set (adding the value only once where there exist duplicate ** prefixes). */ for(i=0; i<(pIdx->nSample-1); i++){ if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){ diff --git a/src/btmutex.c b/src/btmutex.c index 9672687fe0..f9fe5b3dde 100644 --- a/src/btmutex.c +++ b/src/btmutex.c @@ -106,7 +106,7 @@ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ Btree *pLater; /* In most cases, we should be able to acquire the lock we - ** want without having to go throught the ascending lock + ** want without having to go through the ascending lock ** procedure that follows. Just be sure not to block. */ if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ diff --git a/src/btree.c b/src/btree.c index a04302225d..22880f8a54 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file implements a external (disk-based) database using BTrees. +** This file implements an external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ @@ -1144,7 +1144,7 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ */ static int defragmentPage(MemPage *pPage){ int i; /* Loop counter */ - int pc; /* Address of a i-th cell */ + int pc; /* Address of the i-th cell */ int hdr; /* Offset to the page header */ int size; /* Size of a cell */ int usableSize; /* Number of usable bytes on a page */ @@ -2601,7 +2601,7 @@ page1_init_failed: ** false then all cursors are counted. ** ** For the purposes of this routine, a cursor is any cursor that -** is capable of reading or writing to the databse. Cursors that +** is capable of reading or writing to the database. Cursors that ** have been tripped into the CURSOR_FAULT state are not counted. */ static int countValidCursors(BtShared *pBt, int wrOnly){ @@ -3065,7 +3065,7 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); ** calling this function again), return SQLITE_DONE. Or, if an error ** occurs, return some other error code. ** -** More specificly, this function attempts to re-organize the database so +** More specifically, this function attempts to re-organize the database so ** that the last page of the file currently in use is no longer in use. ** ** Parameter nFin is the number of pages that this database would contain @@ -3073,7 +3073,7 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); ** ** If the bCommit parameter is non-zero, this function assumes that the ** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE -** or an error. bCommit is passed true for an auto-vacuum-on-commmit +** or an error. bCommit is passed true for an auto-vacuum-on-commit ** operation, or false for an incremental vacuum. */ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ @@ -3540,7 +3540,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode){ } /* -** Start a statement subtransaction. The subtransaction can can be rolled +** Start a statement subtransaction. The subtransaction can be rolled ** back independently of the main transaction. You must start a transaction ** before starting a subtransaction. The subtransaction is ended automatically ** if the main transaction commits or rolls back. @@ -3774,7 +3774,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ ** compiler to crash when getCellInfo() is implemented as a macro. ** But there is a measureable speed advantage to using the macro on gcc ** (when less compiler optimizations like -Os or -O0 are used and the -** compiler is not doing agressive inlining.) So we use a real function +** compiler is not doing aggressive inlining.) So we use a real function ** for MSVC and a macro for everything else. Ticket #2457. */ #ifndef NDEBUG @@ -3991,7 +3991,7 @@ static int copyPayload( ** ** If the current cursor entry uses one or more overflow pages and the ** eOp argument is not 2, this function may allocate space for and lazily -** popluates the overflow page-list cache array (BtCursor.aOverflow). +** populates the overflow page-list cache array (BtCursor.aOverflow). ** Subsequent calls use this cache to make seeking to the supplied offset ** more efficient. ** @@ -4193,7 +4193,7 @@ static int accessPayload( /* ** Read part of the key associated with cursor pCur. Exactly -** "amt" bytes will be transfered into pBuf[]. The transfer +** "amt" bytes will be transferred into pBuf[]. The transfer ** begins at "offset". ** ** The caller must ensure that pCur is pointing to a valid row @@ -5889,7 +5889,7 @@ static void insertCell( ** The cells are guaranteed to fit on the page. */ static void assemblePage( - MemPage *pPage, /* The page to be assemblied */ + MemPage *pPage, /* The page to be assembled */ int nCell, /* The number of cells to add to this page */ u8 **apCell, /* Pointers to cell bodies */ u16 *aSize /* Sizes of the cells */ @@ -6555,7 +6555,7 @@ static int balance_nonroot( } /* - ** Put the new pages in accending order. This helps to + ** Put the new pages in ascending order. This helps to ** keep entries in the disk file in order so that a scan ** of the table is a linear scan through the file. That ** in turn helps the operating system to deliver pages @@ -6950,7 +6950,7 @@ static int balance(BtCursor *pCur){ /* Call balance_quick() to create a new sibling of pPage on which ** to store the overflow cell. balance_quick() inserts a new cell ** into pParent, which may cause pParent overflow. If this - ** happens, the next interation of the do-loop will balance pParent + ** happens, the next iteration of the do-loop will balance pParent ** use either balance_nonroot() or balance_deeper(). Until this ** happens, the overflow cell is stored in the aBalanceQuickSpace[] ** buffer. @@ -7027,7 +7027,7 @@ static int balance(BtCursor *pCur){ ** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already ** been performed. seekResult is the search result returned (a negative ** number if pCur points at an entry that is smaller than (pKey, nKey), or -** a positive value if pCur points at an etry that is larger than +** a positive value if pCur points at an entry that is larger than ** (pKey, nKey)). ** ** If the seekResult parameter is non-zero, then the caller guarantees that @@ -7184,7 +7184,7 @@ end_insert: /* ** Delete the entry that the cursor is pointing to. The cursor -** is left pointing at a arbitrary location. +** is left pointing at an arbitrary location. */ int sqlite3BtreeDelete(BtCursor *pCur){ Btree *p = pCur->pBtree; @@ -7882,7 +7882,7 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. -** Return 1 if there are 2 ore more references to the page and 0 if +** Return 1 if there are 2 or more references to the page and 0 if ** if this is the first reference to the page. ** ** Also check that the page number is in bounds. diff --git a/src/btreeInt.h b/src/btreeInt.h index d1cdd46983..fbfe47f6bc 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file implements a external (disk-based) database using BTrees. +** This file implements an external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: @@ -135,7 +135,7 @@ ** ** The flags define the format of this btree page. The leaf flag means that ** this page has no children. The zerodata flag means that this page carries -** only keys and no data. The intkey flag means that the key is a integer +** only keys and no data. The intkey flag means that the key is an integer ** which is stored in the key size entry of the cell header rather than in ** the payload area. ** @@ -544,7 +544,7 @@ struct BtCursor { ** seek the cursor to the saved position. ** ** CURSOR_FAULT: -** A unrecoverable error (an I/O error or a malloc failure) has occurred +** An unrecoverable error (an I/O error or a malloc failure) has occurred ** on a different connection that shares the BtShared cache with this ** cursor. The error has left the cache in an inconsistent state. ** Do nothing else with this cursor. Any attempt to use the cursor diff --git a/src/build.c b/src/build.c index 0921d6d25e..6d54befbcc 100644 --- a/src/build.c +++ b/src/build.c @@ -1619,7 +1619,7 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ ** no rowid btree for a WITHOUT ROWID. Instead, the canonical ** data storage is a covering index btree. ** (2) Bypass the creation of the sqlite_master table entry -** for the PRIMARY KEY as the the primary key index is now +** for the PRIMARY KEY as the primary key index is now ** identified by the sqlite_master table entry of the table itself. ** (3) Set the Index.tnum of the PRIMARY KEY Index object in the ** schema to the rootpage from the main table. @@ -1640,7 +1640,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ Vdbe *v = pParse->pVdbe; /* Convert the OP_CreateTable opcode that would normally create the - ** root-page for the table into a OP_CreateIndex opcode. The index + ** root-page for the table into an OP_CreateIndex opcode. The index ** created will become the PRIMARY KEY index. */ if( pParse->addrCrTab ){ @@ -2654,7 +2654,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ int iPartIdxLabel; /* Jump to this label to skip a row */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ - int regRecord; /* Register holding assemblied index record */ + int regRecord; /* Register holding assembled index record */ sqlite3 *db = pParse->db; /* The database connection */ int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); @@ -3254,7 +3254,7 @@ exit_create_index: ** Fill the Index.aiRowEst[] array with default information - information ** to be used when we have not run the ANALYZE command. ** -** aiRowEst[0] is suppose to contain the number of elements in the index. +** aiRowEst[0] is supposed to contain the number of elements in the index. ** Since we do not know, guess 1 million. aiRowEst[1] is an estimate of the ** number of rows in the table that match any particular value of the ** first column of the index. aiRowEst[2] is an estimate of the number @@ -3633,7 +3633,7 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ ** if this is the first term of the FROM clause. pTable and pDatabase ** are the name of the table and database named in the FROM clause term. ** pDatabase is NULL if the database name qualifier is missing - the -** usual case. If the term has a alias, then pAlias points to the +** usual case. If the term has an alias, then pAlias points to the ** alias token. If the term is a subquery, then pSubquery is the ** SELECT statement that the subquery encodes. The pTable and ** pDatabase parameters are NULL for subqueries. The pOn and pUsing diff --git a/src/callback.c b/src/callback.c index 63090899fb..cd213b4b28 100644 --- a/src/callback.c +++ b/src/callback.c @@ -142,7 +142,7 @@ int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ ** ** Each pointer stored in the sqlite3.aCollSeq hash table contains an ** array of three CollSeq structures. The first is the collation sequence -** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. +** preferred for UTF-8, the second UTF-16le, and the third UTF-16be. ** ** Stored immediately after the three collation sequences is a copy of ** the collation sequence name. A pointer to this string is stored in diff --git a/src/complete.c b/src/complete.c index 9e9140085c..6ab6f4a042 100644 --- a/src/complete.c +++ b/src/complete.c @@ -70,7 +70,7 @@ extern const char sqlite3IsEbcdicIdChar[]; ** a statement. ** ** (4) CREATE The keyword CREATE has been seen at the beginning of a -** statement, possibly preceeded by EXPLAIN and/or followed by +** statement, possibly preceded by EXPLAIN and/or followed by ** TEMP or TEMPORARY ** ** (5) TRIGGER We are in the middle of a trigger definition that must be @@ -80,7 +80,7 @@ extern const char sqlite3IsEbcdicIdChar[]; ** the end of a trigger definition. ** ** (7) END We've seen the ";END" of the ";END;" that occurs at the end -** of a trigger difinition. +** of a trigger definition. ** ** Transitions between states above are determined by tokens extracted ** from the input. The following tokens are significant: @@ -123,7 +123,7 @@ int sqlite3_complete(const char *zSql){ }; #else /* If triggers are not supported by this compile then the statement machine - ** used to detect the end of a statement is much simplier + ** used to detect the end of a statement is much simpler */ static const u8 trans[3][3] = { /* Token: */ diff --git a/src/date.c b/src/date.c index f8f4ee0a6b..11b04ea004 100644 --- a/src/date.c +++ b/src/date.c @@ -24,7 +24,7 @@ ** 1970-01-01 00:00:00 is JD 2440587.5 ** 2000-01-01 00:00:00 is JD 2451544.5 ** -** This implemention requires years to be expressed as a 4-digit number +** This implementation requires years to be expressed as a 4-digit number ** which means that only dates between 0000-01-01 and 9999-12-31 can ** be represented, even though julian day numbers allow a much wider ** range of dates. diff --git a/src/delete.c b/src/delete.c index af83903c42..b97407400b 100644 --- a/src/delete.c +++ b/src/delete.c @@ -90,7 +90,7 @@ void sqlite3MaterializeView( Parse *pParse, /* Parsing context */ Table *pView, /* View definition */ Expr *pWhere, /* Optional WHERE clause to be added */ - int iCur /* Cursor number for ephemerial table */ + int iCur /* Cursor number for ephemeral table */ ){ SelectDest dest; Select *pSel; @@ -248,7 +248,7 @@ void sqlite3DeleteFrom( int addrBypass = 0; /* Address of jump over the delete logic */ int addrLoop = 0; /* Top of the delete loop */ int addrDelete = 0; /* Jump directly to the delete logic */ - int addrEphOpen = 0; /* Instruction to open the Ephermeral table */ + int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ @@ -328,7 +328,7 @@ void sqlite3DeleteFrom( sqlite3BeginWriteOperation(pParse, 1, iDb); /* If we are trying to delete from a view, realize that view into - ** a ephemeral table. + ** an ephemeral table. */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ @@ -382,7 +382,7 @@ void sqlite3DeleteFrom( iRowSet = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); }else{ - /* For a WITHOUT ROWID table, create an ephermeral table used to + /* For a WITHOUT ROWID table, create an ephemeral table used to ** hold all primary keys for rows to be deleted. */ pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); @@ -557,7 +557,7 @@ delete_from_cleanup: return; } /* Make sure "isView" and other macros defined above are undefined. Otherwise -** thely may interfere with compilation of other functions in this file +** they may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ #ifdef isView #undef isView diff --git a/src/expr.c b/src/expr.c index 1a2465f7ef..cd0983c579 100644 --- a/src/expr.c +++ b/src/expr.c @@ -22,7 +22,7 @@ ** affinity of that column is returned. Otherwise, 0x00 is returned, ** indicating no affinity for the expression. ** -** i.e. the WHERE clause expresssions in the following statements all +** i.e. the WHERE clause expressions in the following statements all ** have an affinity: ** ** CREATE TABLE t1(a); @@ -501,7 +501,7 @@ void sqlite3ExprAttachSubtrees( } /* -** Allocate a Expr node which joins as many as two subtrees. +** Allocate an Expr node which joins as many as two subtrees. ** ** One or both of the subtrees can be NULL. Return a pointer to the new ** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, @@ -611,7 +611,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ ** ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number ** as the previous instance of the same wildcard. Or if this is the first -** instance of the wildcard, the next sequenial variable number is +** instance of the wildcard, the next sequential variable number is ** assigned. */ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ @@ -746,7 +746,7 @@ static int exprStructSize(Expr *p){ ** During expression analysis, extra information is computed and moved into ** later parts of teh Expr object and that extra information might get chopped ** off if the expression is reduced. Note also that it does not work to -** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal +** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal ** to reduce a pristine expression tree from the parser. The implementation ** of dupedExprStructSize() contain multiple assert() statements that attempt ** to enforce this constraint. @@ -815,7 +815,7 @@ static int dupedExprSize(Expr *p, int flags){ ** is not NULL then *pzBuffer is assumed to point to a buffer large enough ** to store the copy of expression p, the copies of p->u.zToken ** (if applicable), and the copies of the p->pLeft and p->pRight expressions, -** if any. Before returning, *pzBuffer is set to the first byte passed the +** if any. Before returning, *pzBuffer is set to the first byte past the ** portion of the buffer copied into by this function. */ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ @@ -1541,7 +1541,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** ** If the RHS of the IN operator is a list or a more complex subquery, then ** an ephemeral table might need to be generated from the RHS and then -** pX->iTable made to point to the ephermeral table instead of an +** pX->iTable made to point to the ephemeral table instead of an ** existing table. ** ** The inFlags parameter must contain exactly one of the bits @@ -1671,7 +1671,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){ ** and IN_INDEX_NOOP is an allowed reply ** and the RHS of the IN operator is a list, not a subquery ** and the RHS is not contant or has two or fewer terms, - ** then it is not worth creating an ephermeral table to evaluate + ** then it is not worth creating an ephemeral table to evaluate ** the IN operator so return IN_INDEX_NOOP. */ if( eType==0 @@ -2758,7 +2758,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } /* Attempt a direct implementation of the built-in COALESCE() and - ** IFNULL() functions. This avoids unnecessary evalation of + ** IFNULL() functions. This avoids unnecessary evaluation of ** arguments past the first non-NULL argument. */ if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){ @@ -3197,7 +3197,7 @@ void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ } /* -** Generate code that evalutes the given expression and puts the result +** Generate code that evaluates the given expression and puts the result ** in register target. ** ** Also make a copy of the expression results into another "cache" register @@ -3552,7 +3552,7 @@ int sqlite3ExprCodeExprList( ** x>=y AND x<=z ** ** Code it as such, taking care to do the common subexpression -** elementation of x. +** elimination of x. */ static void exprCodeBetween( Parse *pParse, /* Parsing and code generating context */ @@ -4289,7 +4289,7 @@ int sqlite3GetTempReg(Parse *pParse){ ** purpose. ** ** If a register is currently being used by the column cache, then -** the dallocation is deferred until the column cache line that uses +** the deallocation is deferred until the column cache line that uses ** the register becomes stale. */ void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ diff --git a/src/fkey.c b/src/fkey.c index 415f35d2f8..e816bd95da 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -173,7 +173,7 @@ ** ** 4) No parent key columns were provided explicitly as part of the ** foreign key definition, and the PRIMARY KEY of the parent table -** consists of a a different number of columns to the child key in +** consists of a different number of columns to the child key in ** the child table. ** ** then non-zero is returned, and a "foreign key mismatch" error loaded diff --git a/src/func.c b/src/func.c index dbc8375541..e338ab842b 100644 --- a/src/func.c +++ b/src/func.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains the C-language implementions for many of the SQL +** This file contains the C-language implementations for many of the SQL ** functions of SQLite. (Some function, and in particular the date and ** time functions, are implemented separately.) */ @@ -1638,7 +1638,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ } /* -** All all of the FuncDef structures in the aBuiltinFunc[] array above +** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as ** a consequence of calling sqlite3_initialize()). ** diff --git a/src/global.c b/src/global.c index 2c14b58abd..22b990699b 100644 --- a/src/global.c +++ b/src/global.c @@ -10,7 +10,7 @@ ** ************************************************************************* ** -** This file contains definitions of global variables and contants. +** This file contains definitions of global variables and constants. */ #include "sqliteInt.h" diff --git a/src/insert.c b/src/insert.c index 3e6982d836..6a3ab8edae 100644 --- a/src/insert.c +++ b/src/insert.c @@ -410,7 +410,7 @@ static int xferOptimization( ** The 4th template is used if the insert statement takes its ** values from a SELECT but the data is being inserted into a table ** that is also read as part of the SELECT. In the third form, -** we have to use a intermediate table to store the results of +** we have to use an intermediate table to store the results of ** the select. The template is like this: ** ** X <- A @@ -575,7 +575,7 @@ void sqlite3Insert( regAutoinc = autoIncBegin(pParse, iDb, pTab); /* Allocate registers for holding the rowid of the new row, - ** the content of the new row, and the assemblied row record. + ** the content of the new row, and the assembled row record. */ regRowid = regIns = pParse->nMem+1; pParse->nMem += pTab->nCol + 1; @@ -1027,7 +1027,7 @@ insert_cleanup: } /* Make sure "isView" and other macros defined above are undefined. Otherwise -** thely may interfere with compilation of other functions in this file +** they may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ #ifdef isView #undef isView @@ -1143,7 +1143,7 @@ void sqlite3GenerateConstraintChecks( int ix; /* Index loop counter */ int nCol; /* Number of columns */ int onError; /* Conflict resolution strategy */ - int j1; /* Addresss of jump instruction */ + int j1; /* Address of jump instruction */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ int ipkTop = 0; /* Top of the rowid change constraint check */ @@ -1547,7 +1547,7 @@ void sqlite3CompleteInsertion( Index *pIdx; /* An index being inserted or updated */ u8 pik_flags; /* flag values passed to the btree insert */ int regData; /* Content registers (after the rowid) */ - int regRec; /* Register holding assemblied record for the table */ + int regRec; /* Register holding assembled record for the table */ int i; /* Loop counter */ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ @@ -1672,7 +1672,7 @@ int sqlite3OpenTableAndIndices( ** The following global variable is incremented whenever the ** transfer optimization is used. This is used for testing ** purposes only - to make sure the transfer optimization really -** is happening when it is suppose to. +** is happening when it is supposed to. */ int sqlite3_xferopt_count; #endif /* SQLITE_TEST */ @@ -1739,7 +1739,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ ** INSERT INTO tab1 SELECT * FROM tab2; ** ** The xfer optimization transfers raw records from tab2 over to tab1. -** Columns are not decoded and reassemblied, which greatly improves +** Columns are not decoded and reassembled, which greatly improves ** performance. Raw index records are transferred in the same way. ** ** The xfer optimization is only attempted if tab1 and tab2 are compatible. diff --git a/src/main.c b/src/main.c index fd7151b174..977c786f38 100644 --- a/src/main.c +++ b/src/main.c @@ -2853,9 +2853,9 @@ int sqlite3_get_autocommit(sqlite3 *db){ } /* -** The following routines are subtitutes for constants SQLITE_CORRUPT, +** The following routines are substitutes for constants SQLITE_CORRUPT, ** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error -** constants. They server two purposes: +** constants. They serve two purposes: ** ** 1. Serve as a convenient place to set a breakpoint in a debugger ** to detect when version error conditions occurs. @@ -3169,7 +3169,7 @@ int sqlite3_test_control(int op, ...){ ** IMPORTANT: Changing the PENDING byte from 0x40000000 results in ** an incompatible database file format. Changing the PENDING byte ** while any database connection is open results in undefined and - ** dileterious behavior. + ** deleterious behavior. */ case SQLITE_TESTCTRL_PENDING_BYTE: { rc = PENDING_BYTE; diff --git a/src/mem1.c b/src/mem1.c index 6dbf1058ea..11fc1771ed 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -188,7 +188,7 @@ static int sqlite3MemSize(void *pPrior){ ** ** For this low-level interface, we know that pPrior!=0. Cases where ** pPrior==0 while have been intercepted by higher-level routine and -** redirected to xMalloc. Similarly, we know that nByte>0 becauses +** redirected to xMalloc. Similarly, we know that nByte>0 because ** cases where nByte<=0 will have been intercepted by higher-level ** routines and redirected to xFree. */ diff --git a/src/mem5.c b/src/mem5.c index 67615bb964..1479ddd0d0 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -28,7 +28,7 @@ ** 1. All memory allocations sizes are rounded up to a power of 2. ** ** 2. If two adjacent free blocks are the halves of a larger block, -** then the two blocks are coalesed into the single larger block. +** then the two blocks are coalesced into the single larger block. ** ** 3. New memory is allocated from the first available free block. ** diff --git a/src/memjournal.c b/src/memjournal.c index 65ed378b38..6452cecc37 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -26,7 +26,7 @@ typedef struct FileChunk FileChunk; ** ** The size chosen is a little less than a power of two. That way, ** the FileChunk object will have a size that almost exactly fills -** a power-of-two allocation. This mimimizes wasted space in power-of-two +** a power-of-two allocation. This minimizes wasted space in power-of-two ** memory allocators. */ #define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*))) diff --git a/src/mutex.h b/src/mutex.h index 0978812252..03eb1faadb 100644 --- a/src/mutex.h +++ b/src/mutex.h @@ -25,7 +25,7 @@ ** Figure out what version of the code to use. The choices are ** ** SQLITE_MUTEX_OMIT No mutex logic. Not even stubs. The -** mutexes implemention cannot be overridden +** mutexes implementation cannot be overridden ** at start-time. ** ** SQLITE_MUTEX_NOOP For single-threaded applications. No diff --git a/src/os.h b/src/os.h index 3920a62ee3..2c1b86f913 100644 --- a/src/os.h +++ b/src/os.h @@ -120,7 +120,7 @@ ** shared locks begins at SHARED_FIRST. ** ** The same locking strategy and -** byte ranges are used for Unix. This leaves open the possiblity of having +** byte ranges are used for Unix. This leaves open the possibility of having ** clients on win95, winNT, and unix all talking to the same shared file ** and all locking correctly. To do so would require that samba (or whatever ** tool is being used for file sharing) implements locks correctly between diff --git a/src/os_unix.c b/src/os_unix.c index f63afc6bc5..c4f1d40d44 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -631,7 +631,7 @@ static int unixMutexHeld(void) { #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) /* ** Helper function for printing out trace information from debugging -** binaries. This returns the string represetation of the supplied +** binaries. This returns the string representation of the supplied ** integer lock-type. */ static const char *azFileLock(int eFileLock){ @@ -3098,7 +3098,7 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){ ** NB: If you define USE_PREAD or USE_PREAD64, then it might also ** be necessary to define _XOPEN_SOURCE to be 500. This varies from ** one system to another. Since SQLite does not define USE_PREAD -** any any form by default, we will not attempt to define _XOPEN_SOURCE. +** in any form by default, we will not attempt to define _XOPEN_SOURCE. ** See tickets #2741 and #2681. ** ** To avoid stomping the errno value on a failed read the lastErrno value @@ -3730,7 +3730,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ } /* -** If *pArg is inititially negative then this is a query. Set *pArg to +** If *pArg is initially negative then this is a query. Set *pArg to ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. ** ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. @@ -3937,7 +3937,7 @@ static int unixSectorSize(sqlite3_file *id){ ** Return the device characteristics for the file. ** ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default. -** However, that choice is contraversial since technically the underlying +** However, that choice is controversial since technically the underlying ** file system does not always provide powersafe overwrites. (In other ** words, after a power-loss event, parts of the file that were never ** written might end up being altered.) However, non-PSOW behavior is very, @@ -4909,7 +4909,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ ** looks at the filesystem type and tries to guess the best locking ** strategy from that. ** -** For finder-funtion F, two objects are created: +** For finder-function F, two objects are created: ** ** (1) The real finder-function named "FImpt()". ** @@ -5171,7 +5171,7 @@ static const sqlite3_io_methods #endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ /* -** An abstract type for a pointer to a IO method finder function: +** An abstract type for a pointer to an IO method finder function: */ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); @@ -5485,7 +5485,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** descriptor on the same path, fail, and return an error to SQLite. ** ** Even if a subsequent open() call does succeed, the consequences of - ** not searching for a resusable file descriptor are not dire. */ + ** not searching for a reusable file descriptor are not dire. */ if( 0==osStat(zPath, &sStat) ){ unixInodeInfo *pInode; @@ -5516,7 +5516,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** written to *pMode. If an IO error occurs, an SQLite error code is ** returned and the value of *pMode is not modified. ** -** In most cases cases, this routine sets *pMode to 0, which will become +** In most cases, this routine sets *pMode to 0, which will become ** an indication to robust_open() to create the file using ** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. ** But if the file being opened is a WAL or regular journal file, then @@ -6308,7 +6308,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** proxy path against the values stored in the conch. The conch file is ** stored in the same directory as the database file and the file name ** is patterned after the database file name as ".-conch". -** If the conch file does not exist, or it's contents do not match the +** If the conch file does not exist, or its contents do not match the ** host ID and/or proxy path, then the lock is escalated to an exclusive ** lock and the conch file contents is updated with the host ID and proxy ** path and the lock is downgraded to a shared lock again. If the conch @@ -6360,7 +6360,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will ** force proxy locking to be used for every database file opened, and 0 ** will force automatic proxy locking to be disabled for all database -** files (explicity calling the SQLITE_SET_LOCKPROXYFILE pragma or +** files (explicitly calling the SQLITE_SET_LOCKPROXYFILE pragma or ** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING). */ diff --git a/src/os_win.c b/src/os_win.c index 42d5106e5f..e12ce4e532 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -3128,7 +3128,7 @@ static int winUnlock(sqlite3_file *id, int locktype){ } /* -** If *pArg is inititially negative then this is a query. Set *pArg to +** If *pArg is initially negative then this is a query. Set *pArg to ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. ** ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. @@ -4142,7 +4142,7 @@ static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ }else{ /* FIXME: If Windows truly always prevents truncating or deleting a ** file while a mapping is held, then the following winUnmapfile() call - ** is unnecessary can can be omitted - potentially improving + ** is unnecessary can be omitted - potentially improving ** performance. */ winUnmapfile(pFd); } diff --git a/src/pager.c b/src/pager.c index 681968e3cd..8059bee055 100644 --- a/src/pager.c +++ b/src/pager.c @@ -76,12 +76,12 @@ ** Definition: Two databases (or the same database at two points it time) ** are said to be "logically equivalent" if they give the same answer to ** all queries. Note in particular the content of freelist leaf -** pages can be changed arbitarily without effecting the logical equivalence +** pages can be changed arbitrarily without affecting the logical equivalence ** of the database. ** ** (7) At any time, if any subset, including the empty set and the total set, ** of the unsynced changes to a rollback journal are removed and the -** journal is rolled back, the resulting database file will be logical +** journal is rolled back, the resulting database file will be logically ** equivalent to the database file at the beginning of the transaction. ** ** (8) When a transaction is rolled back, the xTruncate method of the VFS @@ -378,7 +378,7 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ ** ** The exception is when the database file is unlocked as the pager moves ** from ERROR to OPEN state. At this point there may be a hot-journal file -** in the file-system that needs to be rolled back (as part of a OPEN->SHARED +** in the file-system that needs to be rolled back (as part of an OPEN->SHARED ** transition, by the same pager or any other). If the call to xUnlock() ** fails at this point and the pager is left holding an EXCLUSIVE lock, this ** can confuse the call to xCheckReservedLock() call made later as part @@ -461,7 +461,7 @@ struct PagerSavepoint { #define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ /* -** A open page cache is an instance of struct Pager. A description of +** An open page cache is an instance of struct Pager. A description of ** some of the more important member variables follows: ** ** eState @@ -633,7 +633,7 @@ struct Pager { /************************************************************************** ** The following block contains those class members that change during - ** routine opertion. Class members not in this block are either fixed + ** routine operation. Class members not in this block are either fixed ** when the pager is first created or else only change when there is a ** significant mode change (such as changing the page_size, locking_mode, ** or the journal_mode). From another view, these class members describe @@ -2497,7 +2497,7 @@ delmaster_out: ** If the file on disk is currently larger than nPage pages, then use the VFS ** xTruncate() method to truncate it. ** -** Or, it might might be the case that the file on disk is smaller than +** Or, it might be the case that the file on disk is smaller than ** nPage pages. Some operating system implementations can get confused if ** you try to truncate a file to some size that is larger than it ** currently is, so detect this case and write a single zero byte to @@ -2556,7 +2556,7 @@ int sqlite3SectorSize(sqlite3_file *pFile){ /* ** Set the value of the Pager.sectorSize variable for the given ** pager based on the value returned by the xSectorSize method -** of the open database file. The sector size will be used used +** of the open database file. The sector size will be used ** to determine the size and alignment of journal header and ** master journal pointers within created journal files. ** @@ -3758,7 +3758,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ int rc; /* Return code */ /* Check that this is either a no-op (because the requested lock is - ** already held, or one of the transistions that the busy-handler + ** already held), or one of the transitions that the busy-handler ** may be invoked during, according to the comment above ** sqlite3PagerSetBusyhandler(). */ @@ -4386,7 +4386,7 @@ static int pagerStress(void *p, PgHdr *pPg){ ** a rollback or by user request, respectively. ** ** Spilling is also prohibited when in an error state since that could - ** lead to database corruption. In the current implementaton it + ** lead to database corruption. In the current implementation it ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 ** while in the error state, hence it is impossible for this routine to ** be called in the error state. Nevertheless, we include a NEVER() @@ -4926,7 +4926,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){ *pExists = (first!=0); }else if( rc==SQLITE_CANTOPEN ){ /* If we cannot open the rollback journal file in order to see if - ** its has a zero header, that might be due to an I/O error, or + ** it has a zero header, that might be due to an I/O error, or ** it might be due to the race condition described above and in ** ticket #3883. Either way, assume that the journal is hot. ** This might be a false positive. But if it is, then the diff --git a/src/pcache.c b/src/pcache.c index eabfadd4b5..801df2b02a 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -390,7 +390,7 @@ PgHdr *sqlite3PcacheFetchFinish( /* ** Decrement the reference count on a page. If the page is clean and the -** reference count drops to 0, then it is made elible for recycling. +** reference count drops to 0, then it is made eligible for recycling. */ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ assert( p->nRef>0 ); diff --git a/src/pcache1.c b/src/pcache1.c index 82015befce..9d15e8514c 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -13,7 +13,7 @@ ** This file implements the default page cache implementation (the ** sqlite3_pcache interface). It also contains part of the implementation ** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. -** If the default page cache implementation is overriden, then neither of +** If the default page cache implementation is overridden, then neither of ** these two features are available. */ @@ -25,7 +25,7 @@ typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set -** of one or more PCaches that are able to recycle each others unpinned +** of one or more PCaches that are able to recycle each other's unpinned ** pages when they are under memory pressure. A PGroup is an instance of ** the following object. ** diff --git a/src/printf.c b/src/printf.c index 72ace932ba..8e71ad8bc6 100644 --- a/src/printf.c +++ b/src/printf.c @@ -904,7 +904,7 @@ char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ /* ** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting -** the string and before returnning. This routine is intended to be used +** the string and before returning. This routine is intended to be used ** to modify an existing string. For example: ** ** x = sqlite3MPrintf(db, x, "prefix %s suffix", x); diff --git a/src/resolve.c b/src/resolve.c index 935d311346..a77fd9d367 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1118,7 +1118,7 @@ static int resolveOrderGroupBy( } /* -** Resolve names in the SELECT statement p and all of its descendents. +** Resolve names in the SELECT statement p and all of its descendants. */ static int resolveSelectStep(Walker *pWalker, Select *p){ NameContext *pOuterNC; /* Context that contains this SELECT */ diff --git a/src/rowset.c b/src/rowset.c index ba2e056bd4..ff5593892a 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -50,7 +50,7 @@ ** No INSERTs may occurs after a SMALLEST. An assertion will fail if ** that is attempted. ** -** The cost of an INSERT is roughly constant. (Sometime new memory +** The cost of an INSERT is roughly constant. (Sometimes new memory ** has to be allocated on an INSERT.) The cost of a TEST with a new ** batch number is O(NlogN) where N is the number of elements in the RowSet. ** The cost of a TEST using the same batch number is O(logN). The cost @@ -443,8 +443,8 @@ int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ ** Check to see if element iRowid was inserted into the rowset as ** part of any insert batch prior to iBatch. Return 1 or 0. ** -** If this is the first test of a new batch and if there exist entires -** on pRowSet->pEntry, then sort those entires into the forest at +** If this is the first test of a new batch and if there exist entries +** on pRowSet->pEntry, then sort those entries into the forest at ** pRowSet->pForest so that they can be tested. */ int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ diff --git a/src/select.c b/src/select.c index 5508c2e694..31a70bff1b 100644 --- a/src/select.c +++ b/src/select.c @@ -1010,7 +1010,7 @@ int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } ** then the KeyInfo structure is appropriate for initializing a virtual ** index to implement a DISTINCT test. ** -** Space to hold the KeyInfo structure is obtain from malloc. The calling +** Space to hold the KeyInfo structure is obtained from malloc. The calling ** function is responsible for seeing that this structure is eventually ** freed. */ @@ -1541,7 +1541,7 @@ static void generateColumnNames( } /* -** Given a an expression list (which is really the list of expressions +** Given an expression list (which is really the list of expressions ** that form the result set of a SELECT statement) compute appropriate ** column names for a table that would hold the expression list. ** @@ -1614,7 +1614,7 @@ static int selectColumnsFromExprList( } /* Make sure the column name is unique. If the name is not unique, - ** append a integer to the name so that it becomes unique. + ** append an integer to the name so that it becomes unique. */ nName = sqlite3Strlen30(zName); for(j=cnt=0; j5 ** -** The code generated for this simpification gives the same result +** The code generated for this simplification gives the same result ** but only has to scan the data once. And because indices might ** exist on the table t1, a complete scan of the data might be ** avoided. @@ -3242,7 +3242,7 @@ static int flattenSubquery( pSubSrc = pSub->pSrc; assert( pSubSrc ); /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, - ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET + ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET ** because they could be computed at compile-time. But when LIMIT and OFFSET ** became arbitrary expressions, we were forced to add restrictions (13) ** and (14). */ @@ -3628,7 +3628,7 @@ static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){ /* ** The select statement passed as the first argument is an aggregate query. -** The second argment is the associated aggregate-info object. This +** The second argument is the associated aggregate-info object. This ** function tests if the SELECT is of the form: ** ** SELECT count(*) FROM @@ -3958,10 +3958,10 @@ static void selectPopWith(Walker *pWalker, Select *p){ ** fill pTabList->a[].pSelect with a copy of the SELECT statement ** that implements the view. A copy is made of the view's SELECT ** statement so that we can freely modify or delete that statement -** without worrying about messing up the presistent representation +** without worrying about messing up the persistent representation ** of the view. ** -** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword +** (3) Add terms to the WHERE clause to accommodate the NATURAL keyword ** on joins and the ON and USING clause of joins. ** ** (4) Scan the list of columns in the result set (pEList) looking diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d446d2ea98..56dede8ba8 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2094,7 +2094,7 @@ int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); ** turns off all busy handlers. ** ** ^(There can only be a single busy handler for a particular -** [database connection] any any given moment. If another busy handler +** [database connection] at any given moment. If another busy handler ** was defined (using [sqlite3_busy_handler()]) prior to calling ** this routine, that other busy handler is cleared.)^ ** @@ -4164,7 +4164,7 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** object results in undefined behavior. ** ** ^These routines work just like the corresponding [column access functions] -** except that these routines take a single [protected sqlite3_value] object +** except that these routines take a single [protected sqlite3_value] object ** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. ** ** ^The sqlite3_value_text16() interface extracts a UTF-16 string @@ -6357,12 +6357,12 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** the current value is always zero.)^ ** ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(
SQLITE_DBSTATUS_CACHE_USED
-**
This parameter returns the approximate number of of bytes of heap +**
This parameter returns the approximate number of bytes of heap ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
SQLITE_DBSTATUS_SCHEMA_USED
-**
This parameter returns the approximate number of of bytes of heap +**
This parameter returns the approximate number of bytes of heap ** memory used to store the schema for all databases associated ** with the connection - main, temp, and any [ATTACH]-ed databases.)^ ** ^The full amount of memory used by the schemas is reported, even if the @@ -6371,7 +6371,7 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. ** ** [[SQLITE_DBSTATUS_STMT_USED]] ^(
SQLITE_DBSTATUS_STMT_USED
-**
This parameter returns the approximate number of of bytes of heap +**
This parameter returns the approximate number of bytes of heap ** and lookaside memory used by all prepared statements associated with ** the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index ecf93f62f6..b4baea2cc5 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -28,7 +28,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines; ** WARNING: In order to maintain backwards compatibility, add new ** interfaces to the end of this structure only. If you insert new ** interfaces in the middle of this structure, then older different -** versions of SQLite will not be able to load each others' shared +** versions of SQLite will not be able to load each other's shared ** libraries! */ struct sqlite3_api_routines { @@ -254,7 +254,7 @@ struct sqlite3_api_routines { /* ** The following macros redefine the API routines so that they are -** redirected throught the global sqlite3_api structure. +** redirected through the global sqlite3_api structure. ** ** This header file is also used by the loadext.c source file ** (part of the main SQLite library - not an extension) so that diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e56da4edd0..ceacdbb335 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -351,7 +351,7 @@ #endif /* -** Return true (non-zero) if the input is a integer that is too large +** Return true (non-zero) if the input is an integer that is too large ** to fit in 32-bits. This macro is used inside of various testcase() ** macros to verify that we have tested SQLite for large-file support. */ @@ -639,7 +639,7 @@ extern const int sqlite3one; ** all alignment restrictions correct. ** ** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the -** underlying malloc() implemention might return us 4-byte aligned +** underlying malloc() implementation might return us 4-byte aligned ** pointers. In that case, only verify 4-byte alignment. */ #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC @@ -2883,8 +2883,8 @@ int sqlite3CantopenError(int); /* ** FTS4 is really an extension for FTS3. It is enabled using the -** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also all -** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3. +** SQLITE_ENABLE_FTS3 macro. But to avoid confusion we also call +** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3. */ #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3) # define SQLITE_ENABLE_FTS3 diff --git a/src/table.c b/src/table.c index 26bbfb4f45..10b0d627f9 100644 --- a/src/table.c +++ b/src/table.c @@ -182,7 +182,7 @@ int sqlite3_get_table( ** This routine frees the space the sqlite3_get_table() malloced. */ void sqlite3_free_table( - char **azResult /* Result returned from from sqlite3_get_table() */ + char **azResult /* Result returned from sqlite3_get_table() */ ){ if( azResult ){ int i, n; diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 2b98b6aab4..945fd95982 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -760,7 +760,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ /* If there are arguments to the function, make a shallow copy of the ** script object, lappend the arguments, then evaluate the copy. ** - ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated. + ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. ** The new Tcl_Obj contains pointers to the original list elements. ** That way, when Tcl_EvalObjv() is run and shimmers the first element ** of the list to tclCmdNameType, that alternate representation will diff --git a/src/test1.c b/src/test1.c index 34faeaadf8..d050e683f4 100644 --- a/src/test1.c +++ b/src/test1.c @@ -2605,7 +2605,7 @@ static int test_bind( ** SQLite selected to call. The TCL test script implements the ** "test_collate" proc. ** -** Note that this will only work with one intepreter at a time, as the +** Note that this will only work with one interpreter at a time, as the ** interp pointer to use when evaluating the TCL script is stored in ** pTestCollateInterp. */ @@ -3758,7 +3758,7 @@ static int test_prepare_v2( ** Usage: sqlite3_prepare_tkt3134 DB ** ** Generate a prepared statement for a zero-byte string as a test -** for ticket #3134. The string should be preceeded by a zero byte. +** for ticket #3134. The string should be preceded by a zero byte. */ static int test_prepare_tkt3134( void * clientData, diff --git a/src/test_intarray.c b/src/test_intarray.c index efcd21d404..7235fbceda 100644 --- a/src/test_intarray.c +++ b/src/test_intarray.c @@ -37,13 +37,13 @@ struct sqlite3_intarray { typedef struct intarray_vtab intarray_vtab; typedef struct intarray_cursor intarray_cursor; -/* A intarray table object */ +/* An intarray table object */ struct intarray_vtab { sqlite3_vtab base; /* Base class */ sqlite3_intarray *pContent; /* Content of the integer array */ }; -/* A intarray cursor object */ +/* An intarray cursor object */ struct intarray_cursor { sqlite3_vtab_cursor base; /* Base class */ int i; /* Current cursor position */ diff --git a/src/test_malloc.c b/src/test_malloc.c index b937cea7cf..bd0a3d1ffd 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -887,7 +887,7 @@ static int test_memdebug_log( ** ** Set the scratch memory buffer using SQLITE_CONFIG_SCRATCH. ** The buffer is static and is of limited size. N might be -** adjusted downward as needed to accomodate the requested size. +** adjusted downward as needed to accommodate the requested size. ** The revised value of N is returned. ** ** A negative SIZE causes the buffer pointer to be NULL. @@ -927,7 +927,7 @@ static int test_config_scratch( ** ** Set the page-cache memory buffer using SQLITE_CONFIG_PAGECACHE. ** The buffer is static and is of limited size. N might be -** adjusted downward as needed to accomodate the requested size. +** adjusted downward as needed to accommodate the requested size. ** The revised value of N is returned. ** ** A negative SIZE causes the buffer pointer to be NULL. diff --git a/src/test_schema.c b/src/test_schema.c index 00a9f4dd90..4ee18193b0 100644 --- a/src/test_schema.c +++ b/src/test_schema.c @@ -189,7 +189,7 @@ static int schemaNext(sqlite3_vtab_cursor *cur){ /* Set zSql to the SQL to pull the list of tables from the ** sqlite_master (or sqlite_temp_master) table of the database - ** identfied by the row pointed to by the SQL statement pCur->pDbList + ** identified by the row pointed to by the SQL statement pCur->pDbList ** (iterating through a "PRAGMA database_list;" statement). */ if( sqlite3_column_int(pCur->pDbList, 0)==1 ){ diff --git a/src/tokenize.c b/src/tokenize.c index 4017c3b816..3f1de221aa 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -77,7 +77,7 @@ const unsigned char ebcdicToAscii[] = { ** end result. ** ** Ticket #1066. the SQL standard does not allow '$' in the -** middle of identfiers. But many SQL implementations do. +** middle of identifiers. But many SQL implementations do. ** SQLite will allow '$' in identifiers for compatibility. ** But the feature is undocumented. */ diff --git a/src/trigger.c b/src/trigger.c index fc32a663bf..d2e7b5a1e6 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -127,7 +127,7 @@ void sqlite3BeginTrigger( ** ^^^^^^^^ ** ** To maintain backwards compatibility, ignore the database - ** name on pTableName if we are reparsing our of SQLITE_MASTER. + ** name on pTableName if we are reparsing out of SQLITE_MASTER. */ if( db->init.busy && iDb!=1 ){ sqlite3DbFree(db, pTableName->a[0].zDatabase); diff --git a/src/update.c b/src/update.c index e152e9057c..f781a60ccd 100644 --- a/src/update.c +++ b/src/update.c @@ -327,7 +327,7 @@ void sqlite3Update( } /* If we are trying to update a view, realize that view into - ** a ephemeral table. + ** an ephemeral table. */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ @@ -488,7 +488,7 @@ void sqlite3Update( } /* Populate the array of registers beginning at regNew with the new - ** row data. This array is used to check constaints, create the new + ** row data. This array is used to check constants, create the new ** table and index records, and as the values for any new.* references ** made by triggers. ** @@ -668,7 +668,7 @@ update_cleanup: return; } /* Make sure "isView" and other macros defined above are undefined. Otherwise -** thely may interfere with compilation of other functions in this file +** they may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ #ifdef isView #undef isView @@ -681,7 +681,7 @@ update_cleanup: /* ** Generate code for an UPDATE of a virtual table. ** -** The strategy is that we create an ephemerial table that contains +** The strategy is that we create an ephemeral table that contains ** for each row to be changed: ** ** (A) The original rowid of that row. @@ -689,7 +689,7 @@ update_cleanup: ** (C) The content of every column in the row. ** ** Then we loop over this ephemeral table and for each row in -** the ephermeral table call VUpdate. +** the ephemeral table call VUpdate. ** ** When finished, drop the ephemeral table. ** diff --git a/src/util.c b/src/util.c index 839a4a4636..9bb8d89157 100644 --- a/src/util.c +++ b/src/util.c @@ -204,7 +204,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ ** occur. ** ** 2002-Feb-14: This routine is extended to remove MS-Access style -** brackets from around identifers. For example: "[a-b-c]" becomes +** brackets from around identifiers. For example: "[a-b-c]" becomes ** "a-b-c". */ int sqlite3Dequote(char *z){ diff --git a/src/vacuum.c b/src/vacuum.c index 936a44a7fe..4d0c0976a1 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -87,7 +87,7 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ ** step (3) requires additional temporary disk space approximately equal ** to the size of the original database for the rollback journal. ** Hence, temporary disk space that is approximately 2x the size of the -** orginal database is required. Every page of the database is written +** original database is required. Every page of the database is written ** approximately 3 times: Once for step (2) and twice for step (3). ** Two writes per page are required in step (3) because the original ** database content must be written into the rollback journal prior to diff --git a/src/vdbe.c b/src/vdbe.c index 0f6e59bf15..cc9e317e4b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2560,7 +2560,7 @@ case OP_MakeRecord: { ** ------------------------------------------------------------------------ ** ** Data(0) is taken from register P1. Data(1) comes from register P1+1 - ** and so froth. + ** and so forth. ** ** Each type field is a varint representing the serial type of the ** corresponding data element (see sqlite3VdbeSerialType()). The @@ -3547,7 +3547,7 @@ case OP_SeekGT: { /* jump, in3 */ if( pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do - ** the seek, so covert it. */ + ** the seek, so convert it. */ pIn3 = &aMem[pOp->p3]; if( (pIn3->flags & (MEM_Int|MEM_Real))==0 ){ applyNumericAffinity(pIn3, 0); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index ef096bebb6..27b266986a 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -238,7 +238,7 @@ struct Mem { #endif /* -** Each auxilliary data pointer stored by a user defined function +** Each auxiliary data pointer stored by a user defined function ** implementation calling sqlite3_set_auxdata() is stored in an instance ** of this structure. All such structures associated with a single VM ** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed @@ -253,7 +253,7 @@ struct AuxData { }; /* -** The "context" argument for a installable function. A pointer to an +** The "context" argument for an installable function. A pointer to an ** instance of this structure is the first argument to the routines used ** implement the SQL functions. ** diff --git a/src/vdbeapi.c b/src/vdbeapi.c index c4a2eebe08..e141ddfb94 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -212,7 +212,7 @@ int sqlite3_value_type(sqlite3_value* pVal){ ** The following routines are used by user-defined functions to specify ** the function result. ** -** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the +** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the ** result as a string or blob but if the string or blob is too large, it ** then sets the error code to SQLITE_TOOBIG */ @@ -645,7 +645,7 @@ void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ } /* -** Return the auxilary data pointer, if any, for the iArg'th argument to +** Return the auxiliary data pointer, if any, for the iArg'th argument to ** the user-function defined by pCtx. */ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ @@ -660,7 +660,7 @@ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ } /* -** Set the auxilary data pointer and delete function, for the iArg'th +** Set the auxiliary data pointer and delete function, for the iArg'th ** argument to the user-function defined by pCtx. Any previous value is ** deleted by calling the delete function specified when it was set. */ @@ -706,7 +706,7 @@ failed: #ifndef SQLITE_OMIT_DEPRECATED /* -** Return the number of times the Step function of a aggregate has been +** Return the number of times the Step function of an aggregate has been ** called. ** ** This function is deprecated. Do not use it for new code. It is @@ -976,7 +976,7 @@ const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ /* ** Return the name of the database from which a result column derives. ** NULL is returned if the result column is an expression or constant or -** anything else which is not an unabiguous reference to a database column. +** anything else which is not an unambiguous reference to a database column. */ const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ return columnName( @@ -992,7 +992,7 @@ const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ /* ** Return the name of the table from which a result column derives. ** NULL is returned if the result column is an expression or constant or -** anything else which is not an unabiguous reference to a database column. +** anything else which is not an unambiguous reference to a database column. */ const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ return columnName( @@ -1008,7 +1008,7 @@ const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ /* ** Return the name of the table column from which a result column derives. ** NULL is returned if the result column is an expression or constant or -** anything else which is not an unabiguous reference to a database column. +** anything else which is not an unambiguous reference to a database column. */ const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ return columnName( @@ -1288,7 +1288,7 @@ int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ ** Deprecated external interface. Internal/core SQLite code ** should call sqlite3TransferBindings. ** -** Is is misuse to call this routine with statements from different +** It is misuse to call this routine with statements from different ** database connections. But as this is a deprecated interface, we ** will not bother to check for that condition. ** diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 84d7cd3013..a653587319 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -895,7 +895,7 @@ void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ ** routine, then a pointer to a dummy VdbeOp will be returned. That opcode ** is readable but not writable, though it is cast to a writable value. ** The return of a dummy opcode allows the call to continue functioning -** after a OOM fault without having to check to see if the return from +** after an OOM fault without having to check to see if the return from ** this routine is a valid pointer. But because the dummy.opcode is 0, ** dummy will never be written to. This is verified by code inspection and ** by running with Valgrind. @@ -1610,9 +1610,9 @@ void sqlite3VdbeRewind(Vdbe *p){ ** After the VDBE has be prepped, it can be executed by one or more ** calls to sqlite3VdbeExec(). ** -** This function may be called exact once on a each virtual machine. +** This function may be called exactly once on each virtual machine. ** After this routine is called the VM has been "packaged" and is ready -** to run. After this routine is called, futher calls to +** to run. After this routine is called, further calls to ** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects ** the Vdbe from the Parse object that helped generate it so that the ** the Vdbe becomes an independent entity and the Parse object can be @@ -1990,7 +1990,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ /* The complex case - There is a multi-file write-transaction active. ** This requires a master journal file to ensure the transaction is - ** committed atomicly. + ** committed atomically. */ #ifndef SQLITE_OMIT_DISKIO else{ @@ -2638,7 +2638,7 @@ int sqlite3VdbeFinalize(Vdbe *p){ ** from left to right), or ** ** * the corresponding bit in argument mask is clear (where the first -** function parameter corrsponds to bit 0 etc.). +** function parameter corresponds to bit 0 etc.). */ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){ AuxData **pp = &pVdbe->pAuxData; @@ -2742,7 +2742,7 @@ static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){ ** Something has moved cursor "p" out of place. Maybe the row it was ** pointed to was deleted out from under it. Or maybe the btree was ** rebalanced. Whatever the cause, try to restore "p" to the place it -** is suppose to be pointing. If the row was deleted out from under the +** is supposed to be pointing. If the row was deleted out from under the ** cursor, set the cursor to point to a NULL row. */ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ @@ -3267,7 +3267,7 @@ static int vdbeRecordCompareDebug( assert( mem1.zMalloc==0 ); /* rc==0 here means that one of the keys ran out of fields and - ** all the fields up to that point were equal. Return the the default_rc + ** all the fields up to that point were equal. Return the default_rc ** value. */ rc = pPKey2->default_rc; @@ -3458,7 +3458,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ ** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero ** or positive integer if key1 is less than, equal to or ** greater than key2. The {nKey1, pKey1} key must be a blob -** created by th OP_MakeRecord opcode of the VDBE. The pPKey2 +** created by the OP_MakeRecord opcode of the VDBE. The pPKey2 ** key must be a parsed key such as obtained from ** sqlite3VdbeParseRecord. ** @@ -3648,7 +3648,7 @@ int sqlite3VdbeRecordCompare( assert( mem1.zMalloc==0 ); /* rc==0 here means that one or both of the keys ran out of fields and - ** all the fields up to that point were equal. Return the the default_rc + ** all the fields up to that point were equal. Return the default_rc ** value. */ assert( CORRUPT_DB || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) diff --git a/src/vdbemem.c b/src/vdbemem.c index 95e23c61a7..ea4def3f86 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -37,7 +37,7 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ ** ** (1) Memory in Mem.zMalloc and managed by the Mem object ** (2) Memory to be freed using Mem.xDel - ** (3) An ephermal string or blob + ** (3) An ephemeral string or blob ** (4) A static string or blob */ if( (p->flags & (MEM_Str|MEM_Blob)) && p->z!=0 ){ @@ -240,7 +240,7 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){ ** used for converting values to text for returning to the user (i.e. via ** sqlite3_value_text()), or for ensuring that values to be used as btree ** keys are strings. In the former case a NULL pointer is returned the -** user and the later is an internal programming error. +** user and the latter is an internal programming error. */ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ int fg = pMem->flags; @@ -405,7 +405,7 @@ static i64 doubleToInt64(double r){ ** If pMem is an integer, then the value is exact. If pMem is ** a floating-point then the value returned is the integer part. ** If pMem is a string or blob, then we make an attempt to convert -** it into a integer and return that. If pMem represents an +** it into an integer and return that. If pMem represents an ** an SQL-NULL value, return 0. ** ** If pMem represents a string value, its encoding might be changed. @@ -697,7 +697,7 @@ int sqlite3VdbeMemTooBig(Mem *p){ #ifdef SQLITE_DEBUG /* -** This routine prepares a memory cell for modication by breaking +** This routine prepares a memory cell for modification by breaking ** its link to a shallow copy and by marking any current shallow ** copies of this cell as invalid. ** diff --git a/src/vdbesort.c b/src/vdbesort.c index 7318ea409e..d1ccf6089d 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -2059,7 +2059,7 @@ static void *vdbePmaReaderBgInit(void *pCtx){ /* ** Use a background thread to invoke vdbePmaReaderIncrMergeInit(INCRINIT_TASK) -** on the the PmaReader object passed as the first argument. +** on the PmaReader object passed as the first argument. ** ** This call will initialize the various fields of the pReadr->pIncr ** structure and, if it is a multi-threaded IncrMerger, launch a diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 4a39e26521..362530a1d9 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -64,7 +64,7 @@ static int findNextHostParameter(const char *zSql, int *pnToken){ ** ALGORITHM: Scan the input string looking for host parameters in any of ** these forms: ?, ?N, $A, @A, :A. Take care to avoid text within ** string literals, quoted identifier names, and comments. For text forms, -** the host parameter index is found by scanning the perpared +** the host parameter index is found by scanning the prepared ** statement for the corresponding OP_Variable opcode. Once the host ** parameter index is known, locate the value in p->aVar[]. Then render ** the value as a literal in place of the host parameter name. diff --git a/src/wal.c b/src/wal.c index 70395f8bee..c0861d5be7 100644 --- a/src/wal.c +++ b/src/wal.c @@ -574,7 +574,7 @@ static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ ** The argument to this macro must be of type u32. On a little-endian ** architecture, it returns the u32 value that results from interpreting ** the 4 bytes as a big-endian value. On a big-endian architecture, it -** returns the value that would be produced by intepreting the 4 bytes +** returns the value that would be produced by interpreting the 4 bytes ** of the input value as a little-endian integer. */ #define BYTESWAP32(x) ( \ @@ -988,7 +988,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ assert( idx <= HASHTABLE_NSLOT/2 + 1 ); /* If this is the first entry to be added to this hash-table, zero the - ** entire hash table and aPgno[] array before proceding. + ** entire hash table and aPgno[] array before proceeding. */ if( idx==1 ){ int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); @@ -1646,7 +1646,7 @@ static int walPagesize(Wal *pWal){ ** database file. ** ** This routine uses and updates the nBackfill field of the wal-index header. -** This is the only routine tha will increase the value of nBackfill. +** This is the only routine that will increase the value of nBackfill. ** (A WAL reset or recovery will revert nBackfill to zero, but not increase ** its value.) ** @@ -1950,7 +1950,7 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){ ** wal-index from the WAL before returning. ** ** Set *pChanged to 1 if the wal-index header value in pWal->hdr is -** changed by this opertion. If pWal->hdr is unchanged, set *pChanged +** changed by this operation. If pWal->hdr is unchanged, set *pChanged ** to 0. ** ** If the wal-index header is successfully read, return SQLITE_OK. @@ -2154,7 +2154,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** may have been appended to the log before READ_LOCK(0) was obtained. ** When holding READ_LOCK(0), the reader ignores the entire log file, ** which implies that the database file contains a trustworthy - ** snapshoT. Since holding READ_LOCK(0) prevents a checkpoint from + ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from ** happening, this is usually correct. ** ** However, if frames have been appended to the log (or if the log @@ -2822,7 +2822,7 @@ int sqlite3WalFrames( ** ** Padding and syncing only occur if this set of frames complete a ** transaction and if PRAGMA synchronous=FULL. If synchronous==NORMAL - ** or synchonous==OFF, then no padding or syncing are needed. + ** or synchronous==OFF, then no padding or syncing are needed. ** ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not ** needed and only the sync is done. If padding is needed, then the diff --git a/src/walker.c b/src/walker.c index 016ae77a92..e30bb60b5a 100644 --- a/src/walker.c +++ b/src/walker.c @@ -19,7 +19,7 @@ /* ** Walk an expression tree. Invoke the callback once for each node -** of the expression, while decending. (In other words, the callback +** of the expression, while descending. (In other words, the callback ** is invoked before visiting children.) ** ** The return value from the callback should be one of the WRC_* diff --git a/src/where.c b/src/where.c index 921baa29eb..5b990fc108 100644 --- a/src/where.c +++ b/src/where.c @@ -701,7 +701,7 @@ static int isLikeOrGlob( ** value of the variable means there is no need to invoke the LIKE ** function, then no OP_Variable will be added to the program. ** This causes problems for the sqlite3_bind_parameter_name() - ** API. To workaround them, add a dummy OP_Variable here. + ** API. To work around them, add a dummy OP_Variable here. */ int r1 = sqlite3GetTempReg(pParse); sqlite3ExprCodeTarget(pParse, pRight, r1); @@ -821,7 +821,7 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ ** appropriate for indexing exist. ** ** All examples A through E above satisfy case 2. But if a term -** also statisfies case 1 (such as B) we know that the optimizer will +** also satisfies case 1 (such as B) we know that the optimizer will ** always prefer case 1, so in that case we pretend that case 2 is not ** satisfied. ** @@ -979,7 +979,7 @@ static void exprAnalyzeOrTerm( } if( (chngToIN & getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){ /* This term must be of the form t1.a==t2.b where t2 is in the - ** chngToIN set but t1 is not. This term will be either preceeded + ** chngToIN set but t1 is not. This term will be either preceded ** or follwed by an inverted copy (t2.b==t1.a). Skip this term ** and use its inversion. */ testcase( pOrTerm->wtFlags & TERM_COPIED ); @@ -1390,7 +1390,7 @@ static void exprAnalyze( } /* -** This function searches pList for a entry that matches the iCol-th column +** This function searches pList for an entry that matches the iCol-th column ** of index pIdx. ** ** If such an expression is found, its index in pList->a[] is returned. If @@ -2140,7 +2140,7 @@ static int whereRangeSkipScanEst( ** number of rows that the index scan is expected to visit without ** considering the range constraints. If nEq is 0, this is the number of ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) -** to account for the range contraints pLower and pUpper. +** to account for the range constraints pLower and pUpper. ** ** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be ** used, a single range inequality reduces the search space by a factor of 4. @@ -3417,7 +3417,7 @@ static Bitmask codeOneLoopStart( ** B: ** ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then - ** use an ephermeral index instead of a RowSet to record the primary + ** use an ephemeral index instead of a RowSet to record the primary ** keys of the rows we have already seen. ** */ @@ -3468,7 +3468,7 @@ static Bitmask codeOneLoopStart( } /* Initialize the rowset register to contain NULL. An SQL NULL is - ** equivalent to an empty rowset. Or, create an ephermeral index + ** equivalent to an empty rowset. Or, create an ephemeral index ** capable of holding primary keys in the case of a WITHOUT ROWID. ** ** Also initialize regReturn to contain the address of the instruction @@ -4723,7 +4723,7 @@ static int whereLoopAddBtree( ApplyCostMultiplier(pNew->rSetup, pTab->costMult); /* TUNING: Each index lookup yields 20 rows in the table. This ** is more than the usual guess of 10 rows, since we have no way - ** of knowning how selective the index will ultimately be. It would + ** of knowing how selective the index will ultimately be. It would ** not be unreasonable to make this value much larger. */ pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut); @@ -5153,7 +5153,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ ** strict. With GROUP BY and DISTINCT the only requirement is that ** equivalent rows appear immediately adjacent to one another. GROUP BY ** and DISTINCT do not require rows to appear in any particular order as long -** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT +** as equivalent rows are grouped together. Thus for GROUP BY and DISTINCT ** the pOrderBy terms can be matched in any order. With ORDER BY, the ** pOrderBy terms must be matched in strict left-to-right order. */ diff --git a/src/whereInt.h b/src/whereInt.h index 81f4a03667..f17906e63a 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -176,7 +176,7 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int); ** 1. Then using those as a basis to compute the N best WherePath objects ** of length 2. And so forth until the length of WherePaths equals the ** number of nodes in the FROM clause. The best (lowest cost) WherePath -** at the end is the choosen query plan. +** at the end is the chosen query plan. */ struct WherePath { Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */ From 2ee53412888324b00964a8766f4f78ccc80218a9 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 6 Sep 2014 16:49:40 +0000 Subject: [PATCH 07/30] Fixes to os_unix.c to support database (and other) files larger than 2GiB. FossilOrigin-Name: e7fae33c0754488336ce093189a83dfe1b818d89 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/os_unix.c | 23 ++++++++++++++++++++++- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8ae6336224..bb3b4e6579 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2014-09-05T05:58:37.378 +C Fixes\sto\sos_unix.c\sto\ssupport\sdatabase\s(and\sother)\sfiles\slarger\sthan\s2GiB. +D 2014-09-06T16:49:40.555 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -208,7 +208,7 @@ F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 60d419395e32a8029fa380a80a3da2e9030f635e F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 8525ca79457c5b4673a5fda2774ee39fe155f40f +F src/os_unix.c 22225d7969b3e4d7aaef9804ea5af5d02d7abd6a F src/os_win.c 3c9f7df710cb6c757b04b78bf3d98f03830e67b9 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/pager.c 3e732d2bbdd8d8d95fed0c5ae7e718d73153c4c5 @@ -1193,7 +1193,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 9779c7a9eb1e2bd36e9286331a9314f064014d80 -R 05490459da8c4172c4abbda0933bfe68 -U mistachkin -Z b93a43f7e285c77b049b454cce5380d9 +P 733119067757814609a9cea6b975818607bee4e3 +R da7850c1d5c67f21c676f6a6ed44959c +T *branch * android-large-filles +T *sym-android-large-filles * +T -sym-trunk * +U dan +Z 5be16efe9db58eba68bedd24a6d0231c diff --git a/manifest.uuid b/manifest.uuid index fb28827b7e..2f4152264c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -733119067757814609a9cea6b975818607bee4e3 \ No newline at end of file +e7fae33c0754488336ce093189a83dfe1b818d89 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index f63afc6bc5..d80a706b93 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -299,6 +299,14 @@ static int randomnessPid = 0; # endif #endif +/* +** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek() +** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined. +*/ +#ifdef __ANDROID__ +# define lseek lseek64 +#endif + /* ** Different Unix systems declare open() in different ways. Same use ** open(const char*,int,mode_t). Others use open(const char*,int,...). @@ -708,9 +716,22 @@ static int lockTrace(int fd, int op, struct flock *p){ /* ** Retry ftruncate() calls that fail due to EINTR +** +** All calls to ftruncate() within this file should be made through this wrapper. +** On the Android platform, bypassing the logic below could lead to a corrupt +** database. */ static int robust_ftruncate(int h, sqlite3_int64 sz){ int rc; +#ifdef __ANDROID__ + /* On Android, ftruncate() always uses 32-bit offsets, even if + ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to + ** truncate a file to any size smaller than 2GiB. Silently ignore any + ** such attempts. */ + if( sz>(sqlite3_int64)0x7FFFFFFF ){ + rc = SQLITE_OK; + }else +#endif do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR ); return rc; } @@ -3595,7 +3616,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){ nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; } - rc = robust_ftruncate(pFile->h, (off_t)nByte); + rc = robust_ftruncate(pFile->h, nByte); if( rc ){ pFile->lastErrno = errno; return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); From d45309796bac57233a063af72f0ac5a08bde8a04 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Sep 2014 14:47:53 +0000 Subject: [PATCH 08/30] Non-working preliminary implementation attempts on user authentication. FossilOrigin-Name: 8440f093bac19a41d44ee352744354eab897fe4e --- ext/userauth/user-auth.txt | 151 ++++++++++++++++++++++++++++ ext/userauth/userauth.c | 197 +++++++++++++++++++++++++++++++++++++ ext/userauth/userauth.h | 88 +++++++++++++++++ manifest | 28 +++--- manifest.uuid | 2 +- src/build.c | 18 ++++ src/main.c | 7 ++ src/pragma.c | 6 ++ src/prepare.c | 22 +++++ src/sqliteInt.h | 33 ++++++- 10 files changed, 539 insertions(+), 13 deletions(-) create mode 100644 ext/userauth/user-auth.txt create mode 100644 ext/userauth/userauth.c create mode 100644 ext/userauth/userauth.h diff --git a/ext/userauth/user-auth.txt b/ext/userauth/user-auth.txt new file mode 100644 index 0000000000..dd49dfcfb7 --- /dev/null +++ b/ext/userauth/user-auth.txt @@ -0,0 +1,151 @@ +Activate the user authentication logic by compiling SQLite with +the -DSQLITE_USER_AUTHENTICATION compile-time option. + +The following new APIs are available when user authentication is +activated: + + int sqlite3_user_authenticate( + sqlite3 *db, /* The database connection */ + const char *zUsername, /* Username */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Password or credentials */ + ); + + int sqlite3_user_add( + sqlite3 *db, /* Database connection */ + const char *zUsername, /* Username to be added */ + int isAdmin, /* True to give new user admin privilege */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Password or credentials */ + ); + + int sqlite3_user_change( + sqlite3 *db, /* Database connection */ + const char *zUsername, /* Username to change */ + int isAdmin, /* Modified admin privilege for the user */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Modified password or credentials */ + ); + + int sqlite3_user_delete( + sqlite3 *db, /* Database connection */ + const char *zUsername /* Username to remove */ + ); + +The sqlite3_open(), sqlite3_open16(), and sqlite3_open_v2() interfaces +work as before: they open a new database connection. However, if the +database being opened requires authentication, then the database +connection will be unusable until after sqlite3_user_authenticate() +has been called successfully [1c]. The sqlite3_user_authenticate() call +will return SQLITE_OK if the authentication credentials are accepted +and SQLITE_ERROR if not. + +Calling sqlite3_user_authenticate() on a no-authentication-required +database connection is a harmless no-op. + +If the database is encrypted, then sqlite3_key_v2() must be called first, +with the correct decryption key, prior to invoking sqlite3_user_authenticate(). + +To recapitulate: When opening an existing unencrypted authentication- +required database, the call sequence is: + + sqlite3_open_v2() + sqlite3_user_authenticate(); + /* Database is now usable */ + +To open an existing, encrypted, authentication-required database, the +call sequence is: + + sqlite3_open_v2(); + sqlite3_key_v2(); + sqlite3_user_authenticate(); + /* Database is now usable */ + +When opening a no-authentication-required database, the database +connection is treated as if it was authenticated as an admin user. + +When ATTACH-ing new database files to a connection, each newly attached +database that is an authentication-required database is checked using +the same username and password as supplied to the main database. If that +check fails, then the ATTACH-ed database is unreadable [1g]. + +The sqlite3_user_add() interface can be used (by an admin user only) +to create a new user. When called on a no-authentication-required +database, this routine converts the database into an authentication- +required database [3], automatically makes the added user an +administrator [1b], and logs in the current connection as that user [1a]. +The sqlite3_user_add() interface only works for the "main" database, not +for any ATTACH-ed databases. Any call to sqlite3_user_add() by a +non-admin user results in an error. + +Hence, to create a new, unencrypted, authentication-required database, +the call sequence is: + + sqlite3_open_v2(); + sqlite3_user_add(); + +And to create a new, encrypted, authentication-required database, the call +sequence is: + + sqlite3_open_v2(); + sqlite3_key_v2(); + sqlite3_user_add(); + +The sqlite3_user_delete() interface can be used (by an admin user only) +to delete a user. The currently logged-in user cannot be deleted, +which guarantees that there is always an admin user and hence that +the database cannot be converted into a no-authentication-required +database [3]. + +The sqlite3_user_change() interface can be used to change a users +login credentials or admin privilege. Any user can change their own +login credentials [1b]. Only an admin user can change another users login +credentials or admin privilege setting. No user may change their own +admin privilege setting. + +The sqlite3_set_authorizer() callback is modified to take a 7th parameter +which is the username of the currently logged in user, or NULL for a +no-authentication-required database [1d]. + +----------------------------------------------------------------------------- +Implementation notes: + +An authentication-required database is identified by the presence of a +new table: + + CREATE TABLE sqlite_user( + uname TEXT PRIMARY KEY, + isAdmin BOOLEAN, + pw BLOB + ) WITHOUT ROWID; + +This table is inaccessible (unreadable and unwriteable) to non-admin users +and is read-only for admin users. However, if the same database file is +opened by a version of SQLite that omits the -DSQLITE_USER_AUTHENTICATION +compile-time option, then the sqlite_user table will be readable by +anybody and writeable by anybody if the "PRAGMA writable_schema=ON" +statement is run first. + +The sqlite_user.pw field is encoded by a built-in SQL function +"sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument +is the plaintext password supplied to the sqlite3_user_authenticate() +interface. The second argument is the sqlite_user.pw value and is supplied +so that the function can extra the "salt" used by the password encoder. +the result of sqlite_crypt(X,Y) is another blob which is the value that +ends up being stored in sqlite_user.pw. To verify credentials X supplied +by the sqlite3_user_authenticate() routine, SQLite runs: + + sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw) + +To compute an appropriate sqlite_user.pw value from a new or modified +password X, sqlite_crypt(X,NULL) is run. A new random salt is selected +when the second argument is NULL. + +The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher +which prevents passwords from being revealed by search the raw database +for ASCII text, but is otherwise trivally broken. To truly secure the +passwords, the database should be encrypted using the SQLite Encryption +Extension or similar technology. Or, the application can use the +sqlite3_create_function() interface to provide an alternative +implementation of sqlite_crypt() that computes a stronger password hash, +perhaps using a cryptographic hash function like SHA1. diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c new file mode 100644 index 0000000000..305ae43a11 --- /dev/null +++ b/ext/userauth/userauth.c @@ -0,0 +1,197 @@ +/* +** 2014-09-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the bulk of the implementation of the +** user-authentication extension feature. Some parts of the user- +** authentication code are contained within the SQLite core (in the +** src/ subdirectory of the main source code tree) but those parts +** that could reasonable be separated out are moved into this file. +** +** To compile with the user-authentication feature, append this file to +** end of an SQLite amalgamation, then add the SQLITE_USER_AUTHENTICATION +** compile-time option. See the user-auth.txt file in the same source +** directory as this file for additional information. +*/ +#ifdef SQLITE_USER_AUTHENTICATION + +/* +** Prepare an SQL statement for use by the user authentication logic. +** Return a pointer to the prepared statement on success. Return a +** NULL pointer if there is an error of any kind. +*/ +static sqlite3_stmt *sqlite3UserAuthPrepare( + sqlite3 *db, + const char *zFormat, + ... +){ + sqlite3_stmt *pStmt; + char *zSql; + int rc; + va_list ap; + + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( zSql==0 ) return 0; + savedFlags = db->auth.authFlags; + db->auth.authFlags |= UAUTH_Ovrd; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + db->auth.authFlags = savedFlags; + sqlite3_free(zSql); + if( rc ){ + sqlite3_finalize(pStmt); + pStmt = 0; + } + return pStmt; +} + +/* +** Check to see if database zDb has a "sqlite_user" table and if it does +** whether that table can authenticate zUser with nPw,zPw. +*/ +static int sqlite3UserAuthCheckLogin( + sqlite3 *db, /* The database connection to check */ + const char *zDb, /* Name of specific database to check */ + const char *zUser, /* User name */ + int nPw, /* Size of password in bytes */ + const char *zPw, /* Password */ + int *pbOk /* OUT: write boolean result here */ +){ + sqlite3_stmt *pStmt; + char *zSql; + int rc; + int iResult; + + *pbOk = 0; + iResult = 0; + pStmt = sqlite3UserAuthPrepare(db, + "SELECT 1 FROM \"%w\".sqlite_master " + " WHERE name='sqlite_user' AND type='table'", zDb); + if( pStmt==0 ) return SQLITE_NOMEM; + rc = sqlite3_step(pStmt): + sqlite3_finalize(pStmt); + if( rc==SQLITE_DONE ){ + *pbOk = 1; + return SQLITE_OK; + } + if( rc!=SQLITE_OK ){ + return rc; + } + pStmt = sqlite3UserAuthPrepare(db, + "SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user" + " WHERE uname=?2", zDb); + if( pStmt==0 ) return SQLITE_NOMEM; + sqlite3_bind_blob(pStmt, 1, zPw, nPw, SQLITE_STATIC); + sqlite3_bind_text(pStmt, 2, zUser, -1, SQLITE_STATIC); + rc = sqlite_step(pStmt); + if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){ + *pbOk = sqlite3_column_int(pStmt, 1); + } + sqlite3_finalize(pStmt); + return rc; +} + +/* +** If a database contains the SQLITE_USER table, then the +** sqlite3_user_authenticate() interface must be invoked with an +** appropriate username and password prior to enable read and write +** access to the database. +** +** Return SQLITE_OK on success or SQLITE_ERROR if the username/password +** combination is incorrect or unknown. +** +** If the SQLITE_USER table is not present in the database file, then +** this interface is a harmless no-op returnning SQLITE_OK. +*/ +int sqlite3_user_authenticate( + sqlite3 *db, /* The database connection */ + const char *zUsername, /* Username */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Password or credentials */ +){ + int bOk = 0; + int rc; + + rc = sqlite3UserAuthCheckLogin(db, zUsername, nPw, zPw, &bOk); + if( bOk ){ + db->auth.authFlags = bOk==2 ? UAUTH_Auth|UAUTH_Admin : UAUTH_Auth; + sqlite3_free(db->auth.zAuthUser); + db->auth.zAuthUser = sqlite3_malloc("%s", zUsername); + sqlite3_free(db->auth.zPw); + db->auth.zPw = sqlite3_malloc( nPw+1 ); + if( db->auth.zPw ){ + memcpy(db->auth.zPw,zPw,nPw); + db->auth.nPw = nPw; + rc = SQLITE_OK; + }else{ + rc = SQLITE_NOMEM; + } + }else{ + db->auth.authFlags = 0; + } + return rc; +} + +/* +** The sqlite3_user_add() interface can be used (by an admin user only) +** to create a new user. When called on a no-authentication-required +** database, this routine converts the database into an authentication- +** required database, automatically makes the added user an +** administrator, and logs in the current connection as that user. +** The sqlite3_user_add() interface only works for the "main" database, not +** for any ATTACH-ed databases. Any call to sqlite3_user_add() by a +** non-admin user results in an error. +*/ +int sqlite3_user_add( + sqlite3 *db, /* Database connection */ + const char *zUsername, /* Username to be added */ + int isAdmin, /* True to give new user admin privilege */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Password or credentials */ +){ + if( !DbIsAdmin(db) ) return SQLITE_ERROR; + + return SQLITE_OK; +} + +/* +** The sqlite3_user_change() interface can be used to change a users +** login credentials or admin privilege. Any user can change their own +** login credentials. Only an admin user can change another users login +** credentials or admin privilege setting. No user may change their own +** admin privilege setting. +*/ +int sqlite3_user_change( + sqlite3 *db, /* Database connection */ + const char *zUsername, /* Username to change */ + int isAdmin, /* Modified admin privilege for the user */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Modified password or credentials */ +){ + return SQLITE_OK; +} + +/* +** The sqlite3_user_delete() interface can be used (by an admin user only) +** to delete a user. The currently logged-in user cannot be deleted, +** which guarantees that there is always an admin user and hence that +** the database cannot be converted into a no-authentication-required +** database. +*/ +int sqlite3_user_delete( + sqlite3 *db, /* Database connection */ + const char *zUsername /* Username to remove */ +){ + return SQLITE_OK; +} + +#endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/ext/userauth/userauth.h b/ext/userauth/userauth.h new file mode 100644 index 0000000000..279675f72c --- /dev/null +++ b/ext/userauth/userauth.h @@ -0,0 +1,88 @@ +/* +** 2014-09-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains the application interface definitions for the +** user-authentication extension feature. +** +** To compile with the user-authentication feature, append this file to +** end of an SQLite amalgamation header file ("sqlite3.h"), then add +** the SQLITE_USER_AUTHENTICATION compile-time option. See the +** user-auth.txt file in the same source directory as this file for +** additional information. +*/ +#ifdef SQLITE_USER_AUTHENTICATION + +/* +** If a database contains the SQLITE_USER table, then the +** sqlite3_user_authenticate() interface must be invoked with an +** appropriate username and password prior to enable read and write +** access to the database. +** +** Return SQLITE_OK on success or SQLITE_ERROR if the username/password +** combination is incorrect or unknown. +** +** If the SQLITE_USER table is not present in the database file, then +** this interface is a harmless no-op returnning SQLITE_OK. +*/ +int sqlite3_user_authenticate( + sqlite3 *db, /* The database connection */ + const char *zUsername, /* Username */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Password or credentials */ +); + +/* +** The sqlite3_user_add() interface can be used (by an admin user only) +** to create a new user. When called on a no-authentication-required +** database, this routine converts the database into an authentication- +** required database, automatically makes the added user an +** administrator, and logs in the current connection as that user. +** The sqlite3_user_add() interface only works for the "main" database, not +** for any ATTACH-ed databases. Any call to sqlite3_user_add() by a +** non-admin user results in an error. +*/ +int sqlite3_user_add( + sqlite3 *db, /* Database connection */ + const char *zUsername, /* Username to be added */ + int isAdmin, /* True to give new user admin privilege */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Password or credentials */ +); + +/* +** The sqlite3_user_change() interface can be used to change a users +** login credentials or admin privilege. Any user can change their own +** login credentials. Only an admin user can change another users login +** credentials or admin privilege setting. No user may change their own +** admin privilege setting. +*/ +int sqlite3_user_change( + sqlite3 *db, /* Database connection */ + const char *zUsername, /* Username to change */ + int isAdmin, /* Modified admin privilege for the user */ + int nPW, /* Number of bytes in aPW[] */ + const void *aPW /* Modified password or credentials */ +); + +/* +** The sqlite3_user_delete() interface can be used (by an admin user only) +** to delete a user. The currently logged-in user cannot be deleted, +** which guarantees that there is always an admin user and hence that +** the database cannot be converted into a no-authentication-required +** database. +*/ +int sqlite3_user_delete( + sqlite3 *db, /* Database connection */ + const char *zUsername /* Username to remove */ +); + +#endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/manifest b/manifest index ccd849754b..0b16bdd037 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sos_unix.c\sto\ssupport\sdatabase\s(and\sother)\sfiles\slarger\sthan\s2GiB\son\sAndroid. -D 2014-09-06T17:06:13.410 +C Non-working\spreliminary\simplementation\sattempts\son\suser\sauthentication. +D 2014-09-09T14:47:53.726 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -144,6 +144,9 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 +F ext/userauth/user-auth.txt f471c5a363ab0682b109d85982ea857f9a144ccc +F ext/userauth/userauth.c cea064a9b66d7497c74cc504b3a01d7f390cbe6e +F ext/userauth/userauth.h efbfb68ff083749ad63b12dcb5877b936c3458d6 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -171,7 +174,7 @@ F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc -F src/build.c 8cb237719c185eec7bd8449b2e747491ded11932 +F src/build.c 8b4c67c9fb638fb2e64b2bcd24677e71a5d61bfc F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a @@ -190,7 +193,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 31c2122b7dd05a179049bbf163fd4839f181cbab -F src/main.c e48517e3da289d93ad86e8b7b4f68078df5e6e51 +F src/main.c 26299e9d9a72239f0652ac9a23e04ced3f536e70 F src/malloc.c 954de5f998c23237e04474a3f2159bf483bba65a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f @@ -217,8 +220,8 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa -F src/pragma.c 14bcdb504128a476cce5bbc086d5226c5e46c225 -F src/prepare.c 3842c1dfc0b053458e3adcf9f6efc48e03e3fe3d +F src/pragma.c e4f6421d7a1f23cd21bf281f2d8c56874879e1d0 +F src/prepare.c 9548c8efb80dbc14b0d54d58574c8a7414cde4db F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb @@ -228,7 +231,7 @@ F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50 F src/sqlite.h.in 64a77f2822f1325b12050972003184f99b655a0f F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4 -F src/sqliteInt.h 4d1b0488f097aa7be346176c4d5e3cc1e25d99da +F src/sqliteInt.h 883f905f17a78bb09061a8efa4f2708faa6ffacc F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08 @@ -1193,7 +1196,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 e62aab5e9290503869e1f4d5e0fefd2b4dee0a69 9dca7ce55797b3eb617859f6189c1a2ec6f66566 -R 4eacabb789e62917f709201f03eadd53 -U dan -Z f60ed4f30cad7188918c7dd18fc1b985 +P ad7063aa1a0db32cdbe71815545b2edca57d3bcc +R 8d9410cfb98bb3b10637c181b910724f +T *branch * user-auth +T *sym-user-auth * +T -sym-trunk * +U drh +Z 7af3a6ca660957a95167232843af8c9e diff --git a/manifest.uuid b/manifest.uuid index fc5888a5d9..c31b773fe5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad7063aa1a0db32cdbe71815545b2edca57d3bcc \ No newline at end of file +8440f093bac19a41d44ee352744354eab897fe4e \ No newline at end of file diff --git a/src/build.c b/src/build.c index 6d54befbcc..c30645cdc6 100644 --- a/src/build.c +++ b/src/build.c @@ -271,6 +271,16 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ pParse->nested--; } +#if SQLITE_USER_AUTHENTICATION +/* +** Return TRUE if zTable is the name of the system table that stores the +** list of users and their access credentials. +*/ +int sqlite3UserAuthTable(const char *zTable){ + return sqlite3_stricmp(zTable, "sqlite_user")==0; +} +#endif + /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -289,6 +299,11 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ assert( zName!=0 ); /* All mutexes are required for schema access. Make sure we hold them. */ assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); +#if SQLITE_USER_AUTHENTICATION + /* Only the admin user is allowed to know that the sqlite_user table + ** exists */ + if( DbIsAdmin(db)==0 && sqlite3UserAuthTable(zName)!=0 ) return 0; +#endif for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue; @@ -2867,6 +2882,9 @@ Index *sqlite3CreateIndex( assert( pTab!=0 ); assert( pParse->nErr==0 ); if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 +#if SQLITE_USER_AUTHENTICATION + && sqlite3UserAuthTable(pTab->zName)==0 +#endif && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){ sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; diff --git a/src/main.c b/src/main.c index 977c786f38..f5114b7924 100644 --- a/src/main.c +++ b/src/main.c @@ -985,6 +985,10 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ sqlite3ValueFree(db->pErr); sqlite3CloseExtensions(db); +#if SQLITE_USER_AUTHENTICATION + sqlite3_free(db->auth.zAuthUser); + sqlite3_free(db->auth.zAuthPW); +#endif db->magic = SQLITE_MAGIC_ERROR; @@ -2566,6 +2570,9 @@ static int openDatabase( db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); +#if SQLITE_USER_AUTHENTICATION + db->auth.authFlags = UAUTH_Auth|UAUTH_Admin; +#endif /* The default safety_level for the main database is 'full'; for the temp ** database it is 'NONE'. This matches the pager layer defaults. diff --git a/src/pragma.c b/src/pragma.c index 12446125fb..8ae79bda33 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1397,6 +1397,12 @@ void sqlite3Pragma( ** in auto-commit mode. */ mask &= ~(SQLITE_ForeignKeys); } +#if SQLITE_USER_AUTHENTICATION + if( !DbIsAdmin(db) ){ + /* Do not allow non-admin users to modify the schema arbitrarily */ + mask &= ~(SQLITE_WriteSchema); + } +#endif if( sqlite3GetBoolean(zRight, 0) ){ db->flags |= mask; diff --git a/src/prepare.c b/src/prepare.c index 5b92e88513..3703b35176 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -206,6 +206,9 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ if( ALWAYS(pTab) ){ pTab->tabFlags |= TF_Readonly; } +#if SQLITE_USER_AUTHENTICATION + db->auth.authFlags = UAUTH_Auth|UAUTH_Admin; +#endif /* Create a cursor to hold the database open */ @@ -361,6 +364,14 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } +#if SQLITE_USER_AUTHENTICATION + if( rc==SQLITE_OK && iDb!=1 ){ + if( sqlite3FindTable(db, "sqlite_user", db->aDb[iDb].zName)!=0 ){ + db->auth.authFlags = UAUTH_AuthReqd; + } + } +#endif + /* Jump here for an error that occurs after successfully allocating ** curMain and calling sqlite3BtreeEnter(). For an error that occurs @@ -720,6 +731,17 @@ static int sqlite3LockAndPrepare( sqlite3_finalize(*ppStmt); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); } +#if SQLITE_USER_AUTHENTICATION + assert( rc==SQLITE_OK || *ppStmt==0 ); +printf("rc=%d init=%d auth=%d sql=[%.50s]\n", rc, db->init.busy, db->auth.authFlags, zSql); +fflush(stdout); + if( rc==SQLITE_OK && !DbIsAuth(db) && db->init.busy==0 ){ + sqlite3_finalize(*ppStmt); + *ppStmt = 0; + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "user not authenticated"); + rc = SQLITE_ERROR; + } +#endif sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); assert( rc==SQLITE_OK || *ppStmt==0 ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ceacdbb335..ae43014c4c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -988,6 +988,35 @@ struct FuncDefHash { FuncDef *a[23]; /* Hash table for functions */ }; +#ifdef SQLITE_USER_AUTHENTICATION +/* +** Information held in the "sqlite3" database connection object and used +** to manage user authentication. +*/ +typedef struct sqlite3_userauth sqlite3_userauth; +struct sqlite3_userauth { + u8 authFlags; /* Status flags for user authentication */ + int nAuthPW; /* Size of the zAuthPW in bytes */ + char *zAuthPW; /* Password used to authenticate */ + char *zAuthUser; /* User name used to authenticate */ +}; + +/* Allowed values for sqlite3_userauth.authFlags */ +#define UAUTH_Ovrd 0x01 /* Do not enforce access restrictions */ +#define UAUTH_Auth 0x02 /* True if the user has authenticated */ +#define UAUTH_Admin 0x04 /* True if the user is an administrator */ +#define UAUTH_AuthReqd 0x08 /* True if main has an sqlite_user table */ + +/* Macros for accessing sqlite3.auth.authFlags */ +#define DbIsAuth(D) (((D)->auth.authFlags&UAUTH_Auth)!=0) +#define DbIsAdmin(D) (((D)->auth.authFlags&UAUTH_Admin)!=0) + +/* Functions used only by user authorization logic */ +int sqlite3UserAuthTable(const char*); + +#endif /* SQLITE_USER_AUTHENTICATION */ + + /* ** Each database connection is an instance of the following structure. */ @@ -1082,7 +1111,6 @@ struct sqlite3 { i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ - #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MASTER ** mutex, not by sqlite3.mutex. They are used by code in notify.c. @@ -1100,6 +1128,9 @@ struct sqlite3 { void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif +#ifdef SQLITE_USER_AUTHENTICATION + sqlite3_userauth auth; /* User authentication information */ +#endif }; /* From da4ca9d19cf92628f4989d95185f3b1fa1418e6d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Sep 2014 17:27:35 +0000 Subject: [PATCH 09/30] Add new APIs that take 64-bit length parameters: sqlite3_malloc64(), sqlite3_realloc64(), sqlite3_bind_blob64(), sqlite3_bind_texte64(), sqlite3_result_blob64(), and sqlite3_result_texte64(). Internal memory allocation routines also now use 64-bit unsigned length parameters for safety. Also add the sqlite3_msize() interface. Fix the sqlite3_get_table() to use sqlite3_realloc64() to avoid a integer overflow problem. FossilOrigin-Name: 94954850cf2e1ec0b7f590c7f46cdc54c72558ce --- manifest | 31 +++++++++++--------- manifest.uuid | 2 +- src/btree.c | 2 +- src/func.c | 2 +- src/malloc.c | 42 ++++++++++++++++++--------- src/pager.c | 2 +- src/sqlite.h.in | 76 ++++++++++++++++++++++++++++++++++++++----------- src/sqliteInt.h | 16 +++++------ src/table.c | 10 +++---- src/vdbeapi.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 196 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index ccd849754b..ae18c40673 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sos_unix.c\sto\ssupport\sdatabase\s(and\sother)\sfiles\slarger\sthan\s2GiB\son\sAndroid. -D 2014-09-06T17:06:13.410 +C Add\snew\sAPIs\sthat\stake\s64-bit\slength\sparameters:\nsqlite3_malloc64(),\nsqlite3_realloc64(),\nsqlite3_bind_blob64(),\nsqlite3_bind_texte64(),\nsqlite3_result_blob64(),\nand\ssqlite3_result_texte64().\nInternal\smemory\sallocation\sroutines\salso\snow\suse\s64-bit\sunsigned\slength\nparameters\sfor\ssafety.\nAlso\sadd\sthe\ssqlite3_msize()\sinterface.\nFix\sthe\ssqlite3_get_table()\sto\suse\ssqlite3_realloc64()\sto\savoid\sa\ninteger\soverflow\sproblem. +D 2014-09-09T17:27:35.957 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -168,7 +168,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd +F src/btree.c e4916b441bb036897cc69df275a2df3fea4d53b6 F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc F src/build.c 8cb237719c185eec7bd8449b2e747491ded11932 @@ -180,7 +180,7 @@ F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f F src/expr.c 441a7e24e2f7bea9475778fa8acce9e8a69ca8f0 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 -F src/func.c 0517037766e18eff7dce298e6b3a8e6311df75ec +F src/func.c 2ae55b52aa95367ee11d1a8f658605093b13d250 F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -191,7 +191,7 @@ F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 31c2122b7dd05a179049bbf163fd4839f181cbab F src/main.c e48517e3da289d93ad86e8b7b4f68078df5e6e51 -F src/malloc.c 954de5f998c23237e04474a3f2159bf483bba65a +F src/malloc.c cc015821ba267ad5c91dc8761d0498a3fc3ce6ce F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f @@ -211,7 +211,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c addd023b26c623fec4dedc110fc4370a65b4768c F src/os_win.c 0a4042ef35f322e86fa01f6c8884c5e645b911e7 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 -F src/pager.c 31da9594ad4c3b5851bb6fe1a95c33835ab7ddce +F src/pager.c c6c809987f0c6a4e27634099d062d425527de173 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be @@ -225,13 +225,13 @@ F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c b4457526cee73c0b69fad42f799f619b1d5a8a8a F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50 -F src/sqlite.h.in 64a77f2822f1325b12050972003184f99b655a0f +F src/sqlite.h.in cbb079b1d89b45d53d44aab4dc291ce2bac0a4b1 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4 -F src/sqliteInt.h 4d1b0488f097aa7be346176c4d5e3cc1e25d99da +F src/sqliteInt.h 0a9083f9d277bf8ca7e9327c01e01bd01f01a585 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 -F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08 +F src/table.c 218ae2ba022881846741dfc8351aefdf129e0377 F src/tclsqlite.c 8d6d6833c0053f0b3b1aeb1c5c7a7eeff0ad4d3f F src/test1.c 22bfe1ce9f2f3746d682093a475ec0a33e0e55d8 F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712 @@ -288,7 +288,7 @@ F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h b4843c35c3ba533b69d4250f550b5bacf2fb013d -F src/vdbeapi.c e43a6b98f853d8064cc096e349ce47e63d4c72d2 +F src/vdbeapi.c fce69e5e9018ce3189da80eefe62ca67606723bc F src/vdbeaux.c 91fd1e0c54a765838dc61fcf79f31acce035ce38 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a @@ -1193,7 +1193,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 e62aab5e9290503869e1f4d5e0fefd2b4dee0a69 9dca7ce55797b3eb617859f6189c1a2ec6f66566 -R 4eacabb789e62917f709201f03eadd53 -U dan -Z f60ed4f30cad7188918c7dd18fc1b985 +P ad7063aa1a0db32cdbe71815545b2edca57d3bcc +R c9aabba8d6c73d7bad5e8196d2f3fcc0 +T *branch * 64-bit-lengths +T *sym-64-bit-lengths * +T -sym-trunk * +U drh +Z b65eab85daa713d0df4e10d4fe4ad4ae diff --git a/manifest.uuid b/manifest.uuid index fc5888a5d9..f3484cced1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad7063aa1a0db32cdbe71815545b2edca57d3bcc \ No newline at end of file +94954850cf2e1ec0b7f590c7f46cdc54c72558ce \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 22880f8a54..fe34b4a836 100644 --- a/src/btree.c +++ b/src/btree.c @@ -606,7 +606,7 @@ static int saveCursorPosition(BtCursor *pCur){ ** data. */ if( 0==pCur->apPage[0]->intKey ){ - void *pKey = sqlite3Malloc( (int)pCur->nKey ); + void *pKey = sqlite3Malloc( pCur->nKey ); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); if( rc==SQLITE_OK ){ diff --git a/src/func.c b/src/func.c index e338ab842b..eef16d3cab 100644 --- a/src/func.c +++ b/src/func.c @@ -390,7 +390,7 @@ static void *contextMalloc(sqlite3_context *context, i64 nByte){ sqlite3_result_error_toobig(context); z = 0; }else{ - z = sqlite3Malloc((int)nByte); + z = sqlite3Malloc(nByte); if( !z ){ sqlite3_result_error_nomem(context); } diff --git a/src/malloc.c b/src/malloc.c index b4b70350f4..daf646bc30 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -294,11 +294,9 @@ static int mallocWithAlarm(int n, void **pp){ ** Allocate memory. This routine is like sqlite3_malloc() except that it ** assumes the memory subsystem has already been initialized. */ -void *sqlite3Malloc(int n){ +void *sqlite3Malloc(u64 n){ void *p; - if( n<=0 /* IMP: R-65312-04917 */ - || n>=0x7fffff00 - ){ + if( n==0 || n>=0x7fffff00 ){ /* A memory allocation of a number of bytes which is near the maximum ** signed integer value might cause an integer overflow inside of the ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving @@ -310,7 +308,7 @@ void *sqlite3Malloc(int n){ mallocWithAlarm(n, &p); sqlite3_mutex_leave(mem0.mutex); }else{ - p = sqlite3GlobalConfig.m.xMalloc(n); + p = sqlite3GlobalConfig.m.xMalloc((int)n); } assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */ return p; @@ -322,6 +320,12 @@ void *sqlite3Malloc(int n){ ** allocation. */ void *sqlite3_malloc(int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + return n<=0 ? 0 : sqlite3Malloc(n); +} +void *sqlite3_malloc64(sqlite3_uint64 n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif @@ -458,6 +462,9 @@ int sqlite3DbMallocSize(sqlite3 *db, void *p){ return sqlite3GlobalConfig.m.xSize(p); } } +sqlite3_uint64 sqlite3_msize(void *p){ + return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p); +} /* ** Free memory previously obtained from sqlite3Malloc(). @@ -519,13 +526,13 @@ void sqlite3DbFree(sqlite3 *db, void *p){ /* ** Change the size of an existing memory allocation */ -void *sqlite3Realloc(void *pOld, int nBytes){ +void *sqlite3Realloc(void *pOld, u64 nBytes){ int nOld, nNew, nDiff; void *pNew; if( pOld==0 ){ return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */ } - if( nBytes<=0 ){ + if( nBytes==0 ){ sqlite3_free(pOld); /* IMP: R-31593-10574 */ return 0; } @@ -537,7 +544,7 @@ void *sqlite3Realloc(void *pOld, int nBytes){ /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second ** argument to xRealloc is always a value returned by a prior call to ** xRoundup. */ - nNew = sqlite3GlobalConfig.m.xRoundup(nBytes); + nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); if( nOld==nNew ){ pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ @@ -572,6 +579,13 @@ void *sqlite3Realloc(void *pOld, int nBytes){ ** subsystem is initialized prior to invoking sqliteRealloc. */ void *sqlite3_realloc(void *pOld, int n){ +#ifndef SQLITE_OMIT_AUTOINIT + if( sqlite3_initialize() ) return 0; +#endif + if( n<0 ) n = 0; + return sqlite3Realloc(pOld, n); +} +void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif @@ -582,7 +596,7 @@ void *sqlite3_realloc(void *pOld, int n){ /* ** Allocate and zero memory. */ -void *sqlite3MallocZero(int n){ +void *sqlite3MallocZero(u64 n){ void *p = sqlite3Malloc(n); if( p ){ memset(p, 0, n); @@ -594,7 +608,7 @@ void *sqlite3MallocZero(int n){ ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ -void *sqlite3DbMallocZero(sqlite3 *db, int n){ +void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ void *p = sqlite3DbMallocRaw(db, n); if( p ){ memset(p, 0, n); @@ -620,7 +634,7 @@ void *sqlite3DbMallocZero(sqlite3 *db, int n){ ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed ** that all prior mallocs (ex: "a") worked too. */ -void *sqlite3DbMallocRaw(sqlite3 *db, int n){ +void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ void *p; assert( db==0 || sqlite3_mutex_held(db->mutex) ); assert( db==0 || db->pnBytesFreed==0 ); @@ -664,7 +678,7 @@ void *sqlite3DbMallocRaw(sqlite3 *db, int n){ ** Resize the block of memory pointed to by p to n bytes. If the ** resize fails, set the mallocFailed flag in the connection object. */ -void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ +void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ void *pNew = 0; assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); @@ -701,7 +715,7 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){ ** Attempt to reallocate p. If the reallocation fails, then free p ** and set the mallocFailed flag in the database connection. */ -void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){ +void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){ void *pNew; pNew = sqlite3DbRealloc(db, p, n); if( !pNew ){ @@ -731,7 +745,7 @@ char *sqlite3DbStrDup(sqlite3 *db, const char *z){ } return zNew; } -char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){ +char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ char *zNew; if( z==0 ){ return 0; diff --git a/src/pager.c b/src/pager.c index 8059bee055..6ad6f73227 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2428,7 +2428,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ rc = sqlite3OsFileSize(pMaster, &nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; nMasterPtr = pVfs->mxPathname+1; - zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1); + zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1); if( !zMasterJournal ){ rc = SQLITE_NOMEM; goto delmaster_out; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 56dede8ba8..79dd4c34b9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2298,6 +2298,10 @@ char *sqlite3_vsnprintf(int,char*,const char*, va_list); ** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns ** a NULL pointer. ** +** ^The sqlite3_malloc64(N) routine works just like +** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead +** of a signed 32-bit integer. +** ** ^Calling sqlite3_free() with a pointer previously returned ** by sqlite3_malloc() or sqlite3_realloc() releases that memory so ** that it might be reused. ^The sqlite3_free() routine is @@ -2309,24 +2313,38 @@ char *sqlite3_vsnprintf(int,char*,const char*, va_list); ** might result if sqlite3_free() is called with a non-NULL pointer that ** was not obtained from sqlite3_malloc() or sqlite3_realloc(). ** -** ^(The sqlite3_realloc() interface attempts to resize a -** prior memory allocation to be at least N bytes, where N is the -** second parameter. The memory allocation to be resized is the first -** parameter.)^ ^ If the first parameter to sqlite3_realloc() +** ^The sqlite3_realloc(X,N) interface attempts to resize a +** prior memory allocation X to be at least N bytes. +** ^If the X parameter to sqlite3_realloc(X,N) ** is a NULL pointer then its behavior is identical to calling -** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc(). -** ^If the second parameter to sqlite3_realloc() is zero or +** sqlite3_malloc(N). +** ^If the N parameter to sqlite3_realloc(X,N) is zero or ** negative then the behavior is exactly the same as calling -** sqlite3_free(P) where P is the first parameter to sqlite3_realloc(). -** ^sqlite3_realloc() returns a pointer to a memory allocation -** of at least N bytes in size or NULL if sufficient memory is unavailable. +** sqlite3_free(X). +** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation +** of at least N bytes in size or NULL if insufficient memory is available. ** ^If M is the size of the prior allocation, then min(N,M) bytes ** of the prior allocation are copied into the beginning of buffer returned -** by sqlite3_realloc() and the prior allocation is freed. -** ^If sqlite3_realloc() returns NULL, then the prior allocation -** is not freed. +** by sqlite3_realloc(X,N) and the prior allocation is freed. +** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the +** prior allocation is not freed. ** -** ^The memory returned by sqlite3_malloc() and sqlite3_realloc() +** ^The sqlite3_realloc64(X,N) interfaces works the same as +** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead +** of a 32-bit signed integer. +** +** ^If X is a memory allocation previously obtained from sqlite3_malloc(), +** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then +** sqlite3_msize(X) returns the size of that memory allocation in bytes. +** ^The value returned by sqlite3_msize(X) might be larger than the number +** of bytes requested when X was allocated. ^If X is a NULL pointer then +** sqlite3_msize(X) returns zero. If X points to something that is not +** the beginning of memory allocation, or if it points to a formerly +** valid memory allocation that has now been freed, then the behavior +** of sqlite3_msize(X) is undefined and possibly harmful. +** +** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(), +** sqlite3_malloc64(), and sqlite3_realloc64() ** is always aligned to at least an 8 byte boundary, or to a ** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time ** option is used. @@ -2354,8 +2372,11 @@ char *sqlite3_vsnprintf(int,char*,const char*, va_list); ** [sqlite3_free()] or [sqlite3_realloc()]. */ void *sqlite3_malloc(int); +void *sqlite3_malloc64(sqlite3_uint64); void *sqlite3_realloc(void*, int); +void *sqlite3_realloc64(void*, sqlite3_uint64); void sqlite3_free(void*); +sqlite3_uint64 sqlite3_msize(void*); /* ** CAPI3REF: Memory Allocator Statistics @@ -3364,7 +3385,8 @@ typedef struct sqlite3_context sqlite3_context; ** If the fourth parameter to sqlite3_bind_blob() is negative, then ** the behavior is undefined. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() -** or sqlite3_bind_text16() then that parameter must be the byte offset +** or sqlite3_bind_text16() or sqlite3_bind_texte64() then +** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL ** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will @@ -3383,6 +3405,14 @@ typedef struct sqlite3_context sqlite3_context; ** SQLite makes its own private copy of the data immediately, before ** the sqlite3_bind_*() routine returns. ** +** ^The sixth argument to sqlite3_bind_texte64() must be one of +** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] +** to specify the encoding of the text in the third parameter. If +** the sixth argument to sqlite3_bind_texte64() is not how of the +** allowed values shown above, or if the text encoding is different +** from the encoding specified by the sixth parameter, then the behavior +** is undefined. +** ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that ** is filled with zeroes. ^A zeroblob uses a fixed amount of memory ** (just an integer to hold its size) while it is being processed. @@ -3403,6 +3433,9 @@ typedef struct sqlite3_context sqlite3_context; ** ** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an ** [error code] if anything goes wrong. +** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB +** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or +** [SQLITE_MAX_LENGTH]. ** ^[SQLITE_RANGE] is returned if the parameter ** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. ** @@ -3410,12 +3443,16 @@ typedef struct sqlite3_context sqlite3_context; ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, + void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); int sqlite3_bind_int(sqlite3_stmt*, int, int); int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); -int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +int sqlite3_bind_texte64(sqlite3_stmt*, int, const char*, sqlite3_uint64, + void(*)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); @@ -4407,10 +4444,14 @@ typedef void (*sqlite3_destructor_type)(void*); ** of the application-defined function to be NULL. ** ** ^The sqlite3_result_text(), sqlite3_result_text16(), -** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces +** sqlite3_result_text16le(), and sqlite3_result_text16be() ** set the return value of the application-defined function to be ** a text string which is represented as UTF-8, UTF-16 native byte order, ** UTF-16 little endian, or UTF-16 big endian, respectively. +** ^The sqlite3_result_texte64() interface sets the return value of an +** application-defined function to be a text string in an encoding +** specified by the fifth (and last) parameter, which must be one +** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ** ^SQLite takes the text result from the application from ** the 2nd parameter of the sqlite3_result_text* interfaces. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces @@ -4454,6 +4495,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** the [sqlite3_context] pointer, the results are undefined. */ void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +void sqlite3_result_blob64(sqlite3_context*,const void*,sqlite3_uint64,void(*)(void*)); void sqlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); @@ -4464,6 +4506,8 @@ void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); void sqlite3_result_null(sqlite3_context*); void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +void sqlite3_result_texte64(sqlite3_context*, const char*,sqlite3_uint64, + void(*)(void*), unsigned char encoding); void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ceacdbb335..8e3a6364c6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2931,15 +2931,15 @@ int sqlite3Strlen30(const char*); int sqlite3MallocInit(void); void sqlite3MallocEnd(void); -void *sqlite3Malloc(int); -void *sqlite3MallocZero(int); -void *sqlite3DbMallocZero(sqlite3*, int); -void *sqlite3DbMallocRaw(sqlite3*, int); +void *sqlite3Malloc(u64); +void *sqlite3MallocZero(u64); +void *sqlite3DbMallocZero(sqlite3*, u64); +void *sqlite3DbMallocRaw(sqlite3*, u64); char *sqlite3DbStrDup(sqlite3*,const char*); -char *sqlite3DbStrNDup(sqlite3*,const char*, int); -void *sqlite3Realloc(void*, int); -void *sqlite3DbReallocOrFree(sqlite3 *, void *, int); -void *sqlite3DbRealloc(sqlite3 *, void *, int); +char *sqlite3DbStrNDup(sqlite3*,const char*, u64); +void *sqlite3Realloc(void*, u64); +void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); +void *sqlite3DbRealloc(sqlite3 *, void *, u64); void sqlite3DbFree(sqlite3*, void*); int sqlite3MallocSize(void*); int sqlite3DbMallocSize(sqlite3*, void*); diff --git a/src/table.c b/src/table.c index 10b0d627f9..12d0cf548e 100644 --- a/src/table.c +++ b/src/table.c @@ -29,10 +29,10 @@ typedef struct TabResult { char **azResult; /* Accumulated output */ char *zErrMsg; /* Error message text, if an error occurs */ - int nAlloc; /* Slots allocated for azResult[] */ - int nRow; /* Number of rows in the result */ - int nColumn; /* Number of columns in the result */ - int nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ + u32 nAlloc; /* Slots allocated for azResult[] */ + u32 nRow; /* Number of rows in the result */ + u32 nColumn; /* Number of columns in the result */ + u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ int rc; /* Return code from sqlite3_exec() */ } TabResult; @@ -58,7 +58,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ if( p->nData + need > p->nAlloc ){ char **azNew; p->nAlloc = p->nAlloc*2 + need; - azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc ); + azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc ); if( azNew==0 ) goto malloc_failed; p->azResult = azNew; } diff --git a/src/vdbeapi.c b/src/vdbeapi.c index e141ddfb94..087ea5c109 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -215,6 +215,9 @@ int sqlite3_value_type(sqlite3_value* pVal){ ** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the ** result as a string or blob but if the string or blob is too large, it ** then sets the error code to SQLITE_TOOBIG +** +** The invokeValueDestructor(P,X) routine invokes destructor function X() +** on value P is not going to be used and need to be destroyed. */ static void setResultStrOrError( sqlite3_context *pCtx, /* Function context */ @@ -227,6 +230,23 @@ static void setResultStrOrError( sqlite3_result_error_toobig(pCtx); } } +static int invokeValueDestructor( + const void *p, /* Value to destroy */ + void (*xDel)(void*), /* The destructor */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ +){ + if( xDel==0 ){ + /* noop */ + }else if( xDel==SQLITE_TRANSIENT ){ + /* noop */ + }else if( xDel==SQLITE_DYNAMIC ){ + sqlite3_free((void*)p); + }else{ + xDel((void*)p); + } + if( pCtx ) sqlite3_result_error_toobig(pCtx); + return SQLITE_TOOBIG; +} void sqlite3_result_blob( sqlite3_context *pCtx, const void *z, @@ -237,6 +257,19 @@ void sqlite3_result_blob( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, 0, xDel); } +void sqlite3_result_blob64( + sqlite3_context *pCtx, + const void *z, + sqlite3_uint64 n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, 0, xDel); + } +} void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); @@ -276,6 +309,20 @@ void sqlite3_result_text( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } +void sqlite3_result_texte64( + sqlite3_context *pCtx, + const char *z, + sqlite3_uint64 n, + void (*xDel)(void *), + unsigned char enc +){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( n>0x7fffffff ){ + (void)invokeValueDestructor(z, xDel, pCtx); + }else{ + setResultStrOrError(pCtx, z, (int)n, enc, xDel); + } +} #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_text16( sqlite3_context *pCtx, @@ -1125,6 +1172,19 @@ int sqlite3_bind_blob( ){ return bindText(pStmt, i, zData, nData, xDel, 0); } +int sqlite3_bind_blob64( + sqlite3_stmt *pStmt, + int i, + const void *zData, + sqlite3_uint64 nData, + void (*xDel)(void*) +){ + if( nData>0x7fffffff ){ + return invokeValueDestructor(zData, xDel, 0); + }else{ + return bindText(pStmt, i, zData, nData, xDel, 0); + } +} int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; @@ -1166,6 +1226,20 @@ int sqlite3_bind_text( ){ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); } +int sqlite3_bind_texte64( + sqlite3_stmt *pStmt, + int i, + const char *zData, + sqlite3_uint64 nData, + void (*xDel)(void*), + unsigned char enc +){ + if( nData>0x7fffffff ){ + return invokeValueDestructor(zData, xDel, 0); + }else{ + return bindText(pStmt, i, zData, nData, xDel, enc); + } +} #ifndef SQLITE_OMIT_UTF16 int sqlite3_bind_text16( sqlite3_stmt *pStmt, From 0807cc2c29593d4bd1cbe4544bacff0509d1ed0e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Sep 2014 18:41:32 +0000 Subject: [PATCH 10/30] Add new interfaces to the loadable extension mechanism. FossilOrigin-Name: 18d80cbc590165913d82056aa69ddaeea07b76ec --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/loadext.c | 15 ++++++++++++++- src/sqlite3ext.h | 30 ++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ae18c40673..c4063387f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sAPIs\sthat\stake\s64-bit\slength\sparameters:\nsqlite3_malloc64(),\nsqlite3_realloc64(),\nsqlite3_bind_blob64(),\nsqlite3_bind_texte64(),\nsqlite3_result_blob64(),\nand\ssqlite3_result_texte64().\nInternal\smemory\sallocation\sroutines\salso\snow\suse\s64-bit\sunsigned\slength\nparameters\sfor\ssafety.\nAlso\sadd\sthe\ssqlite3_msize()\sinterface.\nFix\sthe\ssqlite3_get_table()\sto\suse\ssqlite3_realloc64()\sto\savoid\sa\ninteger\soverflow\sproblem. -D 2014-09-09T17:27:35.957 +C Add\snew\sinterfaces\sto\sthe\sloadable\sextension\smechanism. +D 2014-09-09T18:41:32.385 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -189,7 +189,7 @@ F src/insert.c 0b073fade178d9dbd990bbb32b4438e50b884a06 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b -F src/loadext.c 31c2122b7dd05a179049bbf163fd4839f181cbab +F src/loadext.c 0cb3e0394c21e7fc513b9e3b013f9675f4c93774 F src/main.c e48517e3da289d93ad86e8b7b4f68078df5e6e51 F src/malloc.c cc015821ba267ad5c91dc8761d0498a3fc3ce6ce F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -227,7 +227,7 @@ F src/select.c b4457526cee73c0b69fad42f799f619b1d5a8a8a F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50 F src/sqlite.h.in cbb079b1d89b45d53d44aab4dc291ce2bac0a4b1 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad -F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4 +F src/sqlite3ext.h b8ff57953a1c160e5aa6e0f03119e90ea41fbb4d F src/sqliteInt.h 0a9083f9d277bf8ca7e9327c01e01bd01f01a585 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 @@ -1193,10 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ad7063aa1a0db32cdbe71815545b2edca57d3bcc -R c9aabba8d6c73d7bad5e8196d2f3fcc0 -T *branch * 64-bit-lengths -T *sym-64-bit-lengths * -T -sym-trunk * +P 94954850cf2e1ec0b7f590c7f46cdc54c72558ce +R c1ce17f309170a7fa900bd5f2fa22c3a U drh -Z b65eab85daa713d0df4e10d4fe4ad4ae +Z 9deb67bcd7039b69f5843b47ed73f48c diff --git a/manifest.uuid b/manifest.uuid index f3484cced1..3f9cdc63c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94954850cf2e1ec0b7f590c7f46cdc54c72558ce \ No newline at end of file +18d80cbc590165913d82056aa69ddaeea07b76ec \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 05045dedb3..be8262989a 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -390,7 +390,20 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_uri_int64, sqlite3_uri_parameter, sqlite3_vsnprintf, - sqlite3_wal_checkpoint_v2 + sqlite3_wal_checkpoint_v2, + /* Version 3.8.7 and later */ + sqlite3_auto_extension, + sqlite3_bind_blob64, + sqlite3_bind_texte64, + sqlite3_cancel_auto_extension, + sqlite3_load_extension, + sqlite3_malloc64, + sqlite3_msize, + sqlite3_realloc64, + sqlite3_reset_auto_extension, + sqlite3_result_blob64, + sqlite3_result_texte64, + sqlite3_strglob }; /* diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index b4baea2cc5..17d6197fb7 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -250,6 +250,23 @@ struct sqlite3_api_routines { const char *(*uri_parameter)(const char*,const char*); char *(*vsnprintf)(int,char*,const char*,va_list); int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); + /* Version 3.8.7 and later */ + int (*auto_extension)(void(*)(void)); + int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, + void(*)(void*)); + int (*bind_texte64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, + void(*)(void*),unsigned char); + int (*cancel_auto_extension)(void(*)(void)); + int (*load_extension)(sqlite3*,const char*,const char*,char**); + void *(*malloc64)(sqlite3_uint64); + sqlite3_uint64 (*msize)(void*); + void *(*realloc64)(void*,sqlite3_uint64); + void (*reset_auto_extension)(void); + void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, + void(*)(void*)); + void (*result_texte64)(sqlite3_context*,const char*,sqlite3_uint64, + void(*)(void*), unsigned char); + int (*strglob)(const char*,const char*); }; /* @@ -467,6 +484,19 @@ struct sqlite3_api_routines { #define sqlite3_uri_parameter sqlite3_api->uri_parameter #define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 +/* Version 3.8.7 and later */ +#define sqlite3_auto_extension sqlite3_api->auto_extension +#define sqlite3_bind_blob64 sqlite3_api->bind_blob64 +#define sqlite3_bind_texte64 sqlite3_api->bind_texte64 +#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension +#define sqlite3_load_extension sqlite3_api->load_extension +#define sqlite3_malloc64 sqlite3_api->malloc64 +#define sqlite3_msize sqlite3_api->msize +#define sqlite3_realloc64 sqlite3_api->realloc64 +#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension +#define sqlite3_result_blob64 sqlite3_api->result_blob64 +#define sqlite3_result_texte64 sqlite3_api->result_texte64 +#define sqlite3_strglob sqlite3_api->strglob #endif /* SQLITE_CORE */ #ifndef SQLITE_CORE From bbf483f8553fb37ac73f58e0ec9f7d1e469792f3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Sep 2014 20:30:24 +0000 Subject: [PATCH 11/30] Change the name of the _texte64() interfaces to just _test64(), without the "e". FossilOrigin-Name: 6ab76c5fedfe568b0f0f34a600f9135bf6558148 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/func.c | 7 ++++--- src/loadext.c | 4 ++-- src/sqlite.h.in | 14 +++++++------- src/sqlite3ext.h | 8 ++++---- src/vdbeapi.c | 4 ++-- 7 files changed, 30 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index c4063387f4..637b73b365 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sinterfaces\sto\sthe\sloadable\sextension\smechanism. -D 2014-09-09T18:41:32.385 +C Change\sthe\sname\sof\sthe\s_texte64()\sinterfaces\sto\sjust\s_test64(),\swithout\sthe\s"e". +D 2014-09-09T20:30:24.037 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f F src/expr.c 441a7e24e2f7bea9475778fa8acce9e8a69ca8f0 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 -F src/func.c 2ae55b52aa95367ee11d1a8f658605093b13d250 +F src/func.c 63a0da710cdef3dd195bde045e55af34d775b851 F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -189,7 +189,7 @@ F src/insert.c 0b073fade178d9dbd990bbb32b4438e50b884a06 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b -F src/loadext.c 0cb3e0394c21e7fc513b9e3b013f9675f4c93774 +F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994 F src/main.c e48517e3da289d93ad86e8b7b4f68078df5e6e51 F src/malloc.c cc015821ba267ad5c91dc8761d0498a3fc3ce6ce F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -225,9 +225,9 @@ F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c b4457526cee73c0b69fad42f799f619b1d5a8a8a F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50 -F src/sqlite.h.in cbb079b1d89b45d53d44aab4dc291ce2bac0a4b1 +F src/sqlite.h.in cabd2e9e3a8acb15c5a0f23317e423a17d111e7d F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad -F src/sqlite3ext.h b8ff57953a1c160e5aa6e0f03119e90ea41fbb4d +F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h 0a9083f9d277bf8ca7e9327c01e01bd01f01a585 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 @@ -288,7 +288,7 @@ F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h b4843c35c3ba533b69d4250f550b5bacf2fb013d -F src/vdbeapi.c fce69e5e9018ce3189da80eefe62ca67606723bc +F src/vdbeapi.c cec65a12dc2fe9072d5108d9f75df57b0324883a F src/vdbeaux.c 91fd1e0c54a765838dc61fcf79f31acce035ce38 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a @@ -1193,7 +1193,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 94954850cf2e1ec0b7f590c7f46cdc54c72558ce -R c1ce17f309170a7fa900bd5f2fa22c3a +P 18d80cbc590165913d82056aa69ddaeea07b76ec +R 3de8eb96dbf21697cafd6a57c5ce9a51 U drh -Z 9deb67bcd7039b69f5843b47ed73f48c +Z 5ae42b376f3f0dc69341930379e42b64 diff --git a/manifest.uuid b/manifest.uuid index 3f9cdc63c8..3cbc755153 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18d80cbc590165913d82056aa69ddaeea07b76ec \ No newline at end of file +6ab76c5fedfe568b0f0f34a600f9135bf6558148 \ No newline at end of file diff --git a/src/func.c b/src/func.c index eef16d3cab..e421b2861d 100644 --- a/src/func.c +++ b/src/func.c @@ -325,13 +325,14 @@ static void substrFunc( for(z2=z; *z2 && p2; p2--){ SQLITE_SKIP_UTF8(z2); } - sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT); + sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, + SQLITE_UTF8); }else{ if( p1+p2>len ){ p2 = len-p1; if( p2<0 ) p2 = 0; } - sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT); + sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); } } @@ -1041,7 +1042,7 @@ static void charFunc( *zOut++ = 0x80 + (u8)(c & 0x3F); } \ } - sqlite3_result_text(context, (char*)z, (int)(zOut-z), sqlite3_free); + sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); } /* diff --git a/src/loadext.c b/src/loadext.c index be8262989a..2a2afd8654 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -394,7 +394,7 @@ static const sqlite3_api_routines sqlite3Apis = { /* Version 3.8.7 and later */ sqlite3_auto_extension, sqlite3_bind_blob64, - sqlite3_bind_texte64, + sqlite3_bind_text64, sqlite3_cancel_auto_extension, sqlite3_load_extension, sqlite3_malloc64, @@ -402,7 +402,7 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_realloc64, sqlite3_reset_auto_extension, sqlite3_result_blob64, - sqlite3_result_texte64, + sqlite3_result_text64, sqlite3_strglob }; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 79dd4c34b9..f9249b05bc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3385,7 +3385,7 @@ typedef struct sqlite3_context sqlite3_context; ** If the fourth parameter to sqlite3_bind_blob() is negative, then ** the behavior is undefined. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() -** or sqlite3_bind_text16() or sqlite3_bind_texte64() then +** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL ** terminated. If any NUL characters occur at byte offsets less than @@ -3405,10 +3405,10 @@ typedef struct sqlite3_context sqlite3_context; ** SQLite makes its own private copy of the data immediately, before ** the sqlite3_bind_*() routine returns. ** -** ^The sixth argument to sqlite3_bind_texte64() must be one of +** ^The sixth argument to sqlite3_bind_text64() must be one of ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] ** to specify the encoding of the text in the third parameter. If -** the sixth argument to sqlite3_bind_texte64() is not how of the +** the sixth argument to sqlite3_bind_text64() is not how of the ** allowed values shown above, or if the text encoding is different ** from the encoding specified by the sixth parameter, then the behavior ** is undefined. @@ -3451,7 +3451,7 @@ int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); int sqlite3_bind_null(sqlite3_stmt*, int); int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); -int sqlite3_bind_texte64(sqlite3_stmt*, int, const char*, sqlite3_uint64, +int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); @@ -4448,7 +4448,7 @@ typedef void (*sqlite3_destructor_type)(void*); ** set the return value of the application-defined function to be ** a text string which is represented as UTF-8, UTF-16 native byte order, ** UTF-16 little endian, or UTF-16 big endian, respectively. -** ^The sqlite3_result_texte64() interface sets the return value of an +** ^The sqlite3_result_text64() interface sets the return value of an ** application-defined function to be a text string in an encoding ** specified by the fifth (and last) parameter, which must be one ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. @@ -4506,8 +4506,8 @@ void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); void sqlite3_result_null(sqlite3_context*); void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -void sqlite3_result_texte64(sqlite3_context*, const char*,sqlite3_uint64, - void(*)(void*), unsigned char encoding); +void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, + void(*)(void*), unsigned char encoding); void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 17d6197fb7..f9a066592d 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -254,7 +254,7 @@ struct sqlite3_api_routines { int (*auto_extension)(void(*)(void)); int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, void(*)(void*)); - int (*bind_texte64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, + int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, void(*)(void*),unsigned char); int (*cancel_auto_extension)(void(*)(void)); int (*load_extension)(sqlite3*,const char*,const char*,char**); @@ -264,7 +264,7 @@ struct sqlite3_api_routines { void (*reset_auto_extension)(void); void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, void(*)(void*)); - void (*result_texte64)(sqlite3_context*,const char*,sqlite3_uint64, + void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, void(*)(void*), unsigned char); int (*strglob)(const char*,const char*); }; @@ -487,7 +487,7 @@ struct sqlite3_api_routines { /* Version 3.8.7 and later */ #define sqlite3_auto_extension sqlite3_api->auto_extension #define sqlite3_bind_blob64 sqlite3_api->bind_blob64 -#define sqlite3_bind_texte64 sqlite3_api->bind_texte64 +#define sqlite3_bind_text64 sqlite3_api->bind_text64 #define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension #define sqlite3_load_extension sqlite3_api->load_extension #define sqlite3_malloc64 sqlite3_api->malloc64 @@ -495,7 +495,7 @@ struct sqlite3_api_routines { #define sqlite3_realloc64 sqlite3_api->realloc64 #define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension #define sqlite3_result_blob64 sqlite3_api->result_blob64 -#define sqlite3_result_texte64 sqlite3_api->result_texte64 +#define sqlite3_result_text64 sqlite3_api->result_text64 #define sqlite3_strglob sqlite3_api->strglob #endif /* SQLITE_CORE */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 087ea5c109..4dccb30c15 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -309,7 +309,7 @@ void sqlite3_result_text( assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } -void sqlite3_result_texte64( +void sqlite3_result_text64( sqlite3_context *pCtx, const char *z, sqlite3_uint64 n, @@ -1226,7 +1226,7 @@ int sqlite3_bind_text( ){ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); } -int sqlite3_bind_texte64( +int sqlite3_bind_text64( sqlite3_stmt *pStmt, int i, const char *zData, From e933b83f029d0c749346391c86a47217f7e294cb Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Sep 2014 17:34:28 +0000 Subject: [PATCH 12/30] Further ideas on user authentication. Not yet working code. FossilOrigin-Name: c8171ecd0d6f097c9e95d5f6643bae8d67f44750 --- ext/userauth/userauth.c | 105 ++++++++++++++++++++++++---------------- main.mk | 11 ++++- manifest | 27 +++++------ manifest.uuid | 2 +- src/build.c | 10 +++- src/main.c | 4 -- src/pragma.c | 2 +- src/prepare.c | 40 ++++++--------- src/sqliteInt.h | 17 +++---- 9 files changed, 117 insertions(+), 101 deletions(-) diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 305ae43a11..518f466f14 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -22,6 +22,7 @@ ** directory as this file for additional information. */ #ifdef SQLITE_USER_AUTHENTICATION +#include "sqliteInt.h" /* ** Prepare an SQL statement for use by the user authentication logic. @@ -42,10 +43,7 @@ static sqlite3_stmt *sqlite3UserAuthPrepare( zSql = sqlite3_vmprintf(zFormat, ap); va_end(ap); if( zSql==0 ) return 0; - savedFlags = db->auth.authFlags; - db->auth.authFlags |= UAUTH_Ovrd; rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - db->auth.authFlags = savedFlags; sqlite3_free(zSql); if( rc ){ sqlite3_finalize(pStmt); @@ -56,49 +54,67 @@ static sqlite3_stmt *sqlite3UserAuthPrepare( /* ** Check to see if database zDb has a "sqlite_user" table and if it does -** whether that table can authenticate zUser with nPw,zPw. +** whether that table can authenticate zUser with nPw,zPw. Write one of +** the UAUTH_* user authorization level codes into *peAuth and return a +** result code. */ -static int sqlite3UserAuthCheckLogin( +static int userAuthCheckLogin( sqlite3 *db, /* The database connection to check */ const char *zDb, /* Name of specific database to check */ - const char *zUser, /* User name */ - int nPw, /* Size of password in bytes */ - const char *zPw, /* Password */ - int *pbOk /* OUT: write boolean result here */ + u8 *peAuth /* OUT: One of UAUTH_* constants */ ){ sqlite3_stmt *pStmt; - char *zSql; int rc; - int iResult; - *pbOk = 0; - iResult = 0; + *peAuth = UAUTH_Unknown; pStmt = sqlite3UserAuthPrepare(db, "SELECT 1 FROM \"%w\".sqlite_master " " WHERE name='sqlite_user' AND type='table'", zDb); - if( pStmt==0 ) return SQLITE_NOMEM; - rc = sqlite3_step(pStmt): + if( pStmt==0 ){ + return SQLITE_NOMEM; + } + rc = sqlite3_step(pStmt); sqlite3_finalize(pStmt); if( rc==SQLITE_DONE ){ - *pbOk = 1; + *peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */ return SQLITE_OK; } - if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_ROW ){ return rc; } + if( db->auth.zAuthUser==0 ){ + *peAuth = UAUTH_Fail; + return SQLITE_OK; + } pStmt = sqlite3UserAuthPrepare(db, "SELECT pw=sqlite_crypt(?1,pw), isAdmin FROM \"%w\".sqlite_user" " WHERE uname=?2", zDb); if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_bind_blob(pStmt, 1, zPw, nPw, SQLITE_STATIC); - sqlite3_bind_text(pStmt, 2, zUser, -1, SQLITE_STATIC); - rc = sqlite_step(pStmt); + sqlite3_bind_blob(pStmt, 1, db->auth.zAuthPW, db->auth.nAuthPW,SQLITE_STATIC); + sqlite3_bind_text(pStmt, 2, db->auth.zAuthUser, -1, SQLITE_STATIC); + rc = sqlite3_step(pStmt); if( rc==SQLITE_ROW && sqlite3_column_int(pStmt,0) ){ - *pbOk = sqlite3_column_int(pStmt, 1); + *peAuth = sqlite3_column_int(pStmt, 1) + UAUTH_User; + }else{ + *peAuth = UAUTH_Fail; } sqlite3_finalize(pStmt); return rc; } +int sqlite3UserAuthCheckLogin( + sqlite3 *db, /* The database connection to check */ + const char *zDb, /* Name of specific database to check */ + u8 *peAuth /* OUT: One of UAUTH_* constants */ +){ + int rc; + u8 savedAuthLevel; + savedAuthLevel = db->auth.authLevel; + db->auth.authLevel = UAUTH_Admin; + rc = userAuthCheckLogin(db, zDb, peAuth); + db->auth.authLevel = savedAuthLevel; + return rc; +} + /* ** If a database contains the SQLITE_USER table, then the @@ -116,29 +132,29 @@ int sqlite3_user_authenticate( sqlite3 *db, /* The database connection */ const char *zUsername, /* Username */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Password or credentials */ + const char *zPW /* Password or credentials */ ){ - int bOk = 0; int rc; - - rc = sqlite3UserAuthCheckLogin(db, zUsername, nPw, zPw, &bOk); - if( bOk ){ - db->auth.authFlags = bOk==2 ? UAUTH_Auth|UAUTH_Admin : UAUTH_Auth; - sqlite3_free(db->auth.zAuthUser); - db->auth.zAuthUser = sqlite3_malloc("%s", zUsername); - sqlite3_free(db->auth.zPw); - db->auth.zPw = sqlite3_malloc( nPw+1 ); - if( db->auth.zPw ){ - memcpy(db->auth.zPw,zPw,nPw); - db->auth.nPw = nPw; - rc = SQLITE_OK; - }else{ - rc = SQLITE_NOMEM; - } - }else{ - db->auth.authFlags = 0; + u8 authLevel = UAUTH_Fail; + db->auth.authLevel = UAUTH_Unknown; + sqlite3_free(db->auth.zAuthUser); + sqlite3_free(db->auth.zAuthPW); + memset(&db->auth, 0, sizeof(db->auth)); + db->auth.zAuthUser = sqlite3_mprintf("%s", zUsername); + if( db->auth.zAuthUser==0 ) return SQLITE_NOMEM; + db->auth.zAuthPW = sqlite3_malloc( nPW+1 ); + if( db->auth.zAuthPW==0 ) return SQLITE_NOMEM; + memcpy(db->auth.zAuthPW,zPW,nPW); + db->auth.nAuthPW = nPW; + rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel); + db->auth.authLevel = authLevel; + if( rc ){ + return rc; /* OOM error, I/O error, etc. */ } - return rc; + if( authLevelauth.authLevelauth.authLevelauth.zAuthUser, zUsername)!=0 + && db->auth.authLevelauth.authLevelauth.authLevelnDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ @@ -348,6 +350,12 @@ Table *sqlite3LocateTable( } pParse->checkSchema = 1; } +#if SQLITE_USER_AUTHENICATION + else if( pParse->db->auth.authLevelaDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); -#if SQLITE_USER_AUTHENTICATION - db->auth.authFlags = UAUTH_Auth|UAUTH_Admin; -#endif - /* The default safety_level for the main database is 'full'; for the temp ** database it is 'NONE'. This matches the pager layer defaults. */ diff --git a/src/pragma.c b/src/pragma.c index 8ae79bda33..cbd593f215 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1398,7 +1398,7 @@ void sqlite3Pragma( mask &= ~(SQLITE_ForeignKeys); } #if SQLITE_USER_AUTHENTICATION - if( !DbIsAdmin(db) ){ + if( db->auth.authLeveltabFlags |= TF_Readonly; } -#if SQLITE_USER_AUTHENTICATION - db->auth.authFlags = UAUTH_Auth|UAUTH_Admin; -#endif /* Create a cursor to hold the database open */ @@ -364,14 +361,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } -#if SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK && iDb!=1 ){ - if( sqlite3FindTable(db, "sqlite_user", db->aDb[iDb].zName)!=0 ){ - db->auth.authFlags = UAUTH_AuthReqd; - } - } -#endif - /* Jump here for an error that occurs after successfully allocating ** curMain and calling sqlite3BtreeEnter(). For an error that occurs @@ -420,8 +409,8 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ ** schema may contain references to objects in other databases. */ #ifndef SQLITE_OMIT_TEMPDB - if( rc==SQLITE_OK && ALWAYS(db->nDb>1) - && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ + assert( db->nDb>1 ); + if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ rc = sqlite3InitOne(db, 1, pzErrMsg); if( rc ){ sqlite3ResetOneSchema(db, 1); @@ -725,23 +714,26 @@ static int sqlite3LockAndPrepare( return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db->mutex); +#if SQLITE_USER_AUTHENTICATION + if( db->auth.authLevelauth.authLevel==UAUTH_Unknown ){ + u8 authLevel = UAUTH_Fail; + sqlite3UserAuthCheckLogin(db, "main", &authLevel); + db->auth.authLevel = authLevel; + } + if( db->auth.authLevelmutex); + return SQLITE_ERROR; + } + } +#endif sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); if( rc==SQLITE_SCHEMA ){ sqlite3_finalize(*ppStmt); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); } -#if SQLITE_USER_AUTHENTICATION - assert( rc==SQLITE_OK || *ppStmt==0 ); -printf("rc=%d init=%d auth=%d sql=[%.50s]\n", rc, db->init.busy, db->auth.authFlags, zSql); -fflush(stdout); - if( rc==SQLITE_OK && !DbIsAuth(db) && db->init.busy==0 ){ - sqlite3_finalize(*ppStmt); - *ppStmt = 0; - sqlite3ErrorWithMsg(db, SQLITE_ERROR, "user not authenticated"); - rc = SQLITE_ERROR; - } -#endif sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); assert( rc==SQLITE_OK || *ppStmt==0 ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ae43014c4c..0849ee842b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -995,24 +995,21 @@ struct FuncDefHash { */ typedef struct sqlite3_userauth sqlite3_userauth; struct sqlite3_userauth { - u8 authFlags; /* Status flags for user authentication */ + u8 authLevel; /* Current authentication level */ int nAuthPW; /* Size of the zAuthPW in bytes */ char *zAuthPW; /* Password used to authenticate */ char *zAuthUser; /* User name used to authenticate */ }; -/* Allowed values for sqlite3_userauth.authFlags */ -#define UAUTH_Ovrd 0x01 /* Do not enforce access restrictions */ -#define UAUTH_Auth 0x02 /* True if the user has authenticated */ -#define UAUTH_Admin 0x04 /* True if the user is an administrator */ -#define UAUTH_AuthReqd 0x08 /* True if main has an sqlite_user table */ - -/* Macros for accessing sqlite3.auth.authFlags */ -#define DbIsAuth(D) (((D)->auth.authFlags&UAUTH_Auth)!=0) -#define DbIsAdmin(D) (((D)->auth.authFlags&UAUTH_Admin)!=0) +/* Allowed values for sqlite3_userauth.authLevel */ +#define UAUTH_Unknown 0 /* Authentication not yet checked */ +#define UAUTH_Fail 1 /* User authentication failed */ +#define UAUTH_User 2 /* Authenticated as a normal user */ +#define UAUTH_Admin 3 /* Authenticated as an administrator */ /* Functions used only by user authorization logic */ int sqlite3UserAuthTable(const char*); +int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); #endif /* SQLITE_USER_AUTHENTICATION */ From f442e33e3a794b198071a9c5f76aa33eb74c3327 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Sep 2014 19:01:14 +0000 Subject: [PATCH 13/30] Add the ".user" shell command and implement the sqlite3_user_add() routine. Incremental check-in. The code compiles but does not work. FossilOrigin-Name: a0455f9deb603bf91684158d911269622720fc1a --- .../{userauth.h => sqlite3userauth.h} | 6 +- ext/userauth/userauth.c | 106 ++++++++++++++---- main.mk | 6 +- manifest | 26 ++--- manifest.uuid | 2 +- src/func.c | 3 + src/prepare.c | 2 +- src/shell.c | 64 +++++++++++ src/sqlite.h.in | 1 + src/sqliteInt.h | 2 + 10 files changed, 178 insertions(+), 40 deletions(-) rename ext/userauth/{userauth.h => sqlite3userauth.h} (95%) diff --git a/ext/userauth/userauth.h b/ext/userauth/sqlite3userauth.h similarity index 95% rename from ext/userauth/userauth.h rename to ext/userauth/sqlite3userauth.h index 279675f72c..9f95e9fe7a 100644 --- a/ext/userauth/userauth.h +++ b/ext/userauth/sqlite3userauth.h @@ -37,7 +37,7 @@ int sqlite3_user_authenticate( sqlite3 *db, /* The database connection */ const char *zUsername, /* Username */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Password or credentials */ + const char *aPW /* Password or credentials */ ); /* @@ -55,7 +55,7 @@ int sqlite3_user_add( const char *zUsername, /* Username to be added */ int isAdmin, /* True to give new user admin privilege */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Password or credentials */ + const char *aPW /* Password or credentials */ ); /* @@ -70,7 +70,7 @@ int sqlite3_user_change( const char *zUsername, /* Username to change */ int isAdmin, /* Modified admin privilege for the user */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Modified password or credentials */ + const char *aPW /* Modified password or credentials */ ); /* diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 518f466f14..05d21bf10e 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -23,6 +23,7 @@ */ #ifdef SQLITE_USER_AUTHENTICATION #include "sqliteInt.h" +#include "sqlite3userauth.h" /* ** Prepare an SQL statement for use by the user authentication logic. @@ -52,6 +53,19 @@ static sqlite3_stmt *sqlite3UserAuthPrepare( return pStmt; } +/* +** Check to see if the sqlite_user table exists in database zDb. +*/ +static int userTableExists(sqlite3 *db, const char *zDb){ + int rc; + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0; + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return rc; +} + /* ** Check to see if database zDb has a "sqlite_user" table and if it does ** whether that table can authenticate zUser with nPw,zPw. Write one of @@ -67,20 +81,8 @@ static int userAuthCheckLogin( int rc; *peAuth = UAUTH_Unknown; - pStmt = sqlite3UserAuthPrepare(db, - "SELECT 1 FROM \"%w\".sqlite_master " - " WHERE name='sqlite_user' AND type='table'", zDb); - if( pStmt==0 ){ - return SQLITE_NOMEM; - } - rc = sqlite3_step(pStmt); - sqlite3_finalize(pStmt); - if( rc==SQLITE_DONE ){ + if( !userTableExists(db, "main") ){ *peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */ - return SQLITE_OK; - } - if( rc!=SQLITE_ROW ){ - return rc; } if( db->auth.zAuthUser==0 ){ *peAuth = UAUTH_Fail; @@ -115,6 +117,42 @@ int sqlite3UserAuthCheckLogin( return rc; } +/* +** Implementation of the sqlite_crypt(X,Y) function. +** +** If Y is NULL then generate a new hash for password X and return that +** hash. If Y is not null, then generate a hash for password X using the +** same salt as the previous hash Y and return the new hash. +*/ +void sqlite3CryptFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + const char *zIn; + int nIn, ii; + u8 *zOut; + char zSalt[8]; + zIn = sqlite3_value_blob(argv[0]); + nIn = sqlite3_value_bytes(argv[0]); + if( sqlite3_value_type(argv[1])==SQLITE_BLOB + && sqlite3_value_bytes(argv[1])==nIn+sizeof(zSalt) + ){ + memcpy(zSalt, sqlite3_value_blob(argv[1]), sizeof(zSalt)); + }else{ + sqlite3_randomness(sizeof(zSalt), zSalt); + } + zOut = sqlite3_malloc( nIn+sizeof(zSalt) ); + if( zOut==0 ){ + sqlite3_result_error_nomem(context); + }else{ + memcpy(zOut, zSalt, sizeof(zSalt)); + for(ii=0; iiauth.nAuthPW = nPW; rc = sqlite3UserAuthCheckLogin(db, "main", &authLevel); db->auth.authLevel = authLevel; + sqlite3ExpirePreparedStatements(db); if( rc ){ return rc; /* OOM error, I/O error, etc. */ } @@ -172,9 +211,37 @@ int sqlite3_user_add( const char *zUsername, /* Username to be added */ int isAdmin, /* True to give new user admin privilege */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Password or credentials */ + const char *aPW /* Password or credentials */ ){ - if( db->auth.authLevelauth.authLevelauth.zAuthUser==0 ){ + assert( isAdmin!=0 ); + sqlite3_user_authenticate(db, zUsername, nPW, aPW); + } return SQLITE_OK; } @@ -190,11 +257,11 @@ int sqlite3_user_change( const char *zUsername, /* Username to change */ int isAdmin, /* Modified admin privilege for the user */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Modified password or credentials */ + const char *aPW /* Modified password or credentials */ ){ - if( db->auth.authLevelauth.authLevelauth.zAuthUser, zUsername)!=0 - && db->auth.authLevelauth.authLevelauth.authLevelauth.authLevelauth.zAuthUser, zUsername)==0 ) return SQLITE_AUTH; return SQLITE_OK; } diff --git a/main.mk b/main.mk index 2de8a230ff..4a7ac02710 100644 --- a/main.mk +++ b/main.mk @@ -46,7 +46,7 @@ # TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3 -TCCX += -I$(TOP)/ext/async +TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth # Object files for the SQLite library. # @@ -216,7 +216,7 @@ SRC += \ $(TOP)/ext/rtree/rtree.c SRC += \ $(TOP)/ext/userauth/userauth.c \ - $(TOP)/ext/userauth/userauth.h + $(TOP)/ext/userauth/sqlite3userauth.h # Generated source code files # @@ -380,7 +380,7 @@ EXTHDR += \ EXTHDR += \ $(TOP)/ext/icu/sqliteicu.h EXTHDR += \ - $(TOP)/ext/userauth/userauth.h + $(TOP)/ext/userauth/sqlite3userauth.h # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. diff --git a/manifest b/manifest index fcb6f3314e..28f2b64a45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sideas\son\suser\sauthentication.\s\sNot\syet\sworking\scode. -D 2014-09-10T17:34:28.937 +C Add\sthe\s".user"\sshell\scommand\sand\simplement\sthe\ssqlite3_user_add()\nroutine.\s\sIncremental\scheck-in.\s\sThe\scode\scompiles\sbut\sdoes\snot\swork. +D 2014-09-10T19:01:14.206 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -144,13 +144,13 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 +F ext/userauth/sqlite3userauth.h 6e15b0006e7b07b7b008c9f9297b3781a7514337 w ext/userauth/userauth.h F ext/userauth/user-auth.txt f471c5a363ab0682b109d85982ea857f9a144ccc -F ext/userauth/userauth.c 0d24bcd4a18b354797b9cc6f8e4ba152d385cebe -F ext/userauth/userauth.h efbfb68ff083749ad63b12dcb5877b936c3458d6 +F ext/userauth/userauth.c 5a3f8a7ac79eb1315c7e0313ff87d8c30e33d837 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk ac53fd5d61941c0ff1f05e710999b64ffd03f069 +F main.mk bbc8b6000ed143a1a8d31d3b4995c359a3188fa1 F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -183,7 +183,7 @@ F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f F src/expr.c 441a7e24e2f7bea9475778fa8acce9e8a69ca8f0 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 -F src/func.c 0517037766e18eff7dce298e6b3a8e6311df75ec +F src/func.c 1b7ac915eb83255eba90906cc2e317b1f29ae5c9 F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -221,17 +221,17 @@ F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3b7b1a5e90804006f44c65464c7032ee6a1d24e3 -F src/prepare.c 51ca716a2f73364d8f57c69c89423a0831d17572 +F src/prepare.c 8c2f992a3b3949ab0bf9d4862f7a271f0af0bd5b F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c b4457526cee73c0b69fad42f799f619b1d5a8a8a -F src/shell.c 713cef4d73c05fc8e12f4960072329d767a05d50 -F src/sqlite.h.in 64a77f2822f1325b12050972003184f99b655a0f +F src/shell.c 4dac2ec625fb15a51b06ab998e7cec8c1e6a40eb +F src/sqlite.h.in 577876beef2264a0b031c0d744c81855983088f9 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4 -F src/sqliteInt.h 10a1f056b6b40449a81cf5d708bc0d9fac053c53 +F src/sqliteInt.h fdc23ef0c5475888d0e532204a7451507ce17206 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08 @@ -1196,7 +1196,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8440f093bac19a41d44ee352744354eab897fe4e -R 6f268f8f48a352ef36f94cb71204780d +P c8171ecd0d6f097c9e95d5f6643bae8d67f44750 +R f252935e505dbc9ddcbfc78d0487cc51 U drh -Z 6484e1728dcc8ed1c2a7dbcf5e6f2393 +Z 5adba3159d6bf335715850631d1526a9 diff --git a/manifest.uuid b/manifest.uuid index cff06d83f6..2ed68f3b13 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8171ecd0d6f097c9e95d5f6643bae8d67f44750 \ No newline at end of file +a0455f9deb603bf91684158d911269622720fc1a \ No newline at end of file diff --git a/src/func.c b/src/func.c index e338ab842b..94ad1b62da 100644 --- a/src/func.c +++ b/src/func.c @@ -1695,6 +1695,9 @@ void sqlite3RegisterGlobalFunctions(void){ FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), +#if SQLITE_USER_AUTHENTICATION + FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), +#endif #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), diff --git a/src/prepare.c b/src/prepare.c index d3531f114b..e1739ba3f6 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -722,7 +722,7 @@ static int sqlite3LockAndPrepare( db->auth.authLevel = authLevel; } if( db->auth.authLevelmutex); return SQLITE_ERROR; } diff --git a/src/shell.c b/src/shell.c index afe01ef1a1..2312a7d321 100644 --- a/src/shell.c +++ b/src/shell.c @@ -33,6 +33,9 @@ #include #include #include "sqlite3.h" +#if SQLITE_USER_AUTHENTICATION +# include "sqlite3userauth.h" +#endif #include #include @@ -3435,6 +3438,67 @@ static int do_meta_command(char *zLine, ShellState *p){ #endif }else +#if SQLITE_USER_AUTHENTICATION + if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ + if( nArg<2 ){ + fprintf(stderr, "Usage: .user SUBCOMMAND ...\n"); + rc = 1; + goto meta_command_exit; + } + if( strcmp(azArg[1],"login")==0 ){ + if( nArg!=4 ){ + fprintf(stderr, "Usage: .user login USER PASSWORD\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_authenticate(p->db, azArg[2], (int)strlen(azArg[3]), azArg[3]); + if( rc ){ + fprintf(stderr, "Authentication failed for user %s\n", azArg[2]); + rc = 1; + } + }else if( strcmp(azArg[1],"add")==0 ){ + if( nArg!=5 ){ + fprintf(stderr, "Usage: .user add USER ISADMIN PASSWORD\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_add(p->db, azArg[2], booleanValue(azArg[3]), + (int)strlen(azArg[4]), azArg[4]); + if( rc ){ + fprintf(stderr, "User-Add failed: %d\n", rc); + rc = 1; + } + }else if( strcmp(azArg[1],"edit")==0 ){ + if( nArg!=5 ){ + fprintf(stderr, "Usage: .user edit USER ISADMIN PASSWORD\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_change(p->db, azArg[2], booleanValue(azArg[3]), + (int)strlen(azArg[4]), azArg[4]); + if( rc ){ + fprintf(stderr, "User-Edit failed: %d\n", rc); + rc = 1; + } + }else if( strcmp(azArg[1],"delete")==0 ){ + if( nArg!=3 ){ + fprintf(stderr, "Usage: .user delete USER\n"); + rc = 1; + goto meta_command_exit; + } + rc = sqlite3_user_delete(p->db, azArg[2]); + if( rc ){ + fprintf(stderr, "User-Delete failed: %d\n", rc); + rc = 1; + } + }else{ + fprintf(stderr, "Usage: .user login|add|edit|delete ...\n"); + rc = 1; + goto meta_command_exit; + } + }else +#endif /* SQLITE_USER_AUTHENTICATION */ + if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 56dede8ba8..e947c3e19a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -492,6 +492,7 @@ int sqlite3_exec( #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) +#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) /* ** CAPI3REF: Flags For File Open Operations diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0849ee842b..9ef4e36208 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1010,6 +1010,8 @@ struct sqlite3_userauth { /* Functions used only by user authorization logic */ int sqlite3UserAuthTable(const char*); int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); +void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); + #endif /* SQLITE_USER_AUTHENTICATION */ From 09e60541aecde780c2d16d7d7e8284235247b375 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 10 Sep 2014 22:46:46 +0000 Subject: [PATCH 14/30] Complete the implementation of the various APIs. Fix several problems. This is another incremental check-in that does not completely work. FossilOrigin-Name: 4eaaa7fa87aa912d24f8b35440ab60310dc08310 --- ext/userauth/userauth.c | 66 ++++++++++++++++++++++++++++++++++------- manifest | 22 +++++++------- manifest.uuid | 2 +- src/ctime.c | 3 ++ src/legacy.c | 2 +- src/prepare.c | 1 + src/test_config.c | 6 ++++ 7 files changed, 78 insertions(+), 24 deletions(-) diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 05d21bf10e..5e00c5cfb2 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -39,12 +39,15 @@ static sqlite3_stmt *sqlite3UserAuthPrepare( char *zSql; int rc; va_list ap; + int savedFlags = db->flags; va_start(ap, zFormat); zSql = sqlite3_vmprintf(zFormat, ap); va_end(ap); if( zSql==0 ) return 0; + db->flags |= SQLITE_WriteSchema; rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + db->flags = savedFlags; sqlite3_free(zSql); if( rc ){ sqlite3_finalize(pStmt); @@ -60,6 +63,11 @@ static int userTableExists(sqlite3 *db, const char *zDb){ int rc; sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); + if( db->init.busy==0 ){ + char *zErr = 0; + sqlite3Init(db, &zErr); + sqlite3DbFree(db, zErr); + } rc = sqlite3FindTable(db, "sqlite_user", zDb)!=0; sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); @@ -83,6 +91,7 @@ static int userAuthCheckLogin( *peAuth = UAUTH_Unknown; if( !userTableExists(db, "main") ){ *peAuth = UAUTH_Admin; /* No sqlite_user table. Everybody is admin. */ + return SQLITE_OK; } if( db->auth.zAuthUser==0 ){ *peAuth = UAUTH_Fail; @@ -100,8 +109,7 @@ static int userAuthCheckLogin( }else{ *peAuth = UAUTH_Fail; } - sqlite3_finalize(pStmt); - return rc; + return sqlite3_finalize(pStmt); } int sqlite3UserAuthCheckLogin( sqlite3 *db, /* The database connection to check */ @@ -230,8 +238,8 @@ int sqlite3_user_add( if( rc ) return rc; } pStmt = sqlite3UserAuthPrepare(db, - "INSERT INTO sqlite_user(uname,isAdmin,sqlite_crypt(pw,NULL))" - " VALUES(%Q,%d,?1)", + "INSERT INTO sqlite_user(uname,isAdmin,pw)" + " VALUES(%Q,%d,sqlite_crypt(?1,NULL))", zUsername, isAdmin!=0); if( pStmt==0 ) return SQLITE_NOMEM; sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); @@ -259,10 +267,31 @@ int sqlite3_user_change( int nPW, /* Number of bytes in aPW[] */ const char *aPW /* Modified password or credentials */ ){ - if( db->auth.authLevelauth.zAuthUser, zUsername)!=0 - && db->auth.authLevelauth.authLevelauth.zAuthUser, zUsername)!=0 ){ + if( db->auth.authLevelauth.authLevel==UAUTH_Admin) ){ + /* Cannot change the isAdmin setting for self */ + return SQLITE_AUTH; + } + if( !userTableExists(db, "main") ){ + /* This routine is a no-op if the user to be modified does not exist */ + return SQLITE_OK; + } + pStmt = sqlite3UserAuthPrepare(db, + "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)" + " WHERE uname=%Q", isAdmin, zUsername); + if( pStmt==0 ) return SQLITE_NOMEM; + sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); + sqlite3_step(pStmt); + return sqlite3_finalize(pStmt); } /* @@ -276,9 +305,24 @@ int sqlite3_user_delete( sqlite3 *db, /* Database connection */ const char *zUsername /* Username to remove */ ){ - if( db->auth.authLevelauth.zAuthUser, zUsername)==0 ) return SQLITE_AUTH; - return SQLITE_OK; + sqlite3_stmt *pStmt; + if( db->auth.authLevelauth.zAuthUser, zUsername)==0 ){ + /* Cannot delete self */ + return SQLITE_AUTH; + } + if( !userTableExists(db, "main") ){ + /* This routine is a no-op if the user to be deleted does not exist */ + return SQLITE_OK; + } + pStmt = sqlite3UserAuthPrepare(db, + "SELECT FROM sqlite_user WHERE uname=%Q", zUsername); + if( pStmt==0 ) return SQLITE_NOMEM; + sqlite3_step(pStmt); + return sqlite3_finalize(pStmt); } #endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/manifest b/manifest index 28f2b64a45..01cd4221fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".user"\sshell\scommand\sand\simplement\sthe\ssqlite3_user_add()\nroutine.\s\sIncremental\scheck-in.\s\sThe\scode\scompiles\sbut\sdoes\snot\swork. -D 2014-09-10T19:01:14.206 +C Complete\sthe\simplementation\sof\sthe\svarious\sAPIs.\s\sFix\sseveral\sproblems.\nThis\sis\sanother\sincremental\scheck-in\sthat\sdoes\snot\scompletely\swork. +D 2014-09-10T22:46:46.526 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -144,9 +144,9 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/userauth/sqlite3userauth.h 6e15b0006e7b07b7b008c9f9297b3781a7514337 w ext/userauth/userauth.h +F ext/userauth/sqlite3userauth.h 6e15b0006e7b07b7b008c9f9297b3781a7514337 F ext/userauth/user-auth.txt f471c5a363ab0682b109d85982ea857f9a144ccc -F ext/userauth/userauth.c 5a3f8a7ac79eb1315c7e0313ff87d8c30e33d837 +F ext/userauth/userauth.c e14ab212e1e2cd3f3a5d324f2c3e0b0c5a950c86 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -177,7 +177,7 @@ F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc F src/build.c 3a61555d469de2e0f5bcd1ac4d58a2a19ab093d5 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 -F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a +F src/ctime.c 16cd19215d9fd849ee2b7509b092f2e0bbd6a958 F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036 F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f F src/expr.c 441a7e24e2f7bea9475778fa8acce9e8a69ca8f0 @@ -190,7 +190,7 @@ F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 0b073fade178d9dbd990bbb32b4438e50b884a06 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d -F src/legacy.c 87c92f4a08e2f70220e3b22a9c3b2482d36a134a +F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 31c2122b7dd05a179049bbf163fd4839f181cbab F src/main.c d15621461fb0c52675eba2b650492ed1beef69ab @@ -221,7 +221,7 @@ F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3b7b1a5e90804006f44c65464c7032ee6a1d24e3 -F src/prepare.c 8c2f992a3b3949ab0bf9d4862f7a271f0af0bd5b +F src/prepare.c 10dd9833d7aa992baf84b8640224853576119d84 F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb @@ -249,7 +249,7 @@ F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c d5f00627c4f47515a57f905806558153cccd7253 +F src/test_config.c 6f721f0337b96d58e81ff69bba101113c8168c2b F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -1196,7 +1196,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c8171ecd0d6f097c9e95d5f6643bae8d67f44750 -R f252935e505dbc9ddcbfc78d0487cc51 +P a0455f9deb603bf91684158d911269622720fc1a +R 7c5d50077d463af5ab8f09588f919ad0 U drh -Z 5adba3159d6bf335715850631d1526a9 +Z 0eb3e0d5d27e81783efc050a8d458d7f diff --git a/manifest.uuid b/manifest.uuid index 2ed68f3b13..5efaf01425 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0455f9deb603bf91684158d911269622720fc1a \ No newline at end of file +4eaaa7fa87aa912d24f8b35440ab60310dc08310 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 286f66e061..6f7ac8fcba 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -368,6 +368,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_USE_ALLOCA "USE_ALLOCA", #endif +#ifdef SQLITE_USER_AUTHENTICATION + "USER_AUTHENTICATION", +#endif #ifdef SQLITE_WIN32_MALLOC "WIN32_MALLOC", #endif diff --git a/src/legacy.c b/src/legacy.c index b8cb90d707..a10006e558 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -125,7 +125,7 @@ exec_out: sqlite3DbFree(db, azCols); rc = sqlite3ApiExit(db, rc); - if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){ + if( rc!=SQLITE_OK && pzErrMsg ){ int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db)); *pzErrMsg = sqlite3Malloc(nErrMsg); if( *pzErrMsg ){ diff --git a/src/prepare.c b/src/prepare.c index e1739ba3f6..c6752548ff 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -394,6 +394,7 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int commit_internal = !(db->flags&SQLITE_InternChanges); assert( sqlite3_mutex_held(db->mutex) ); + assert( db->init.busy==0 ); rc = SQLITE_OK; db->init.busy = 1; for(i=0; rc==SQLITE_OK && inDb; i++){ diff --git a/src/test_config.c b/src/test_config.c index 78c65a8e52..074faf2116 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -603,6 +603,12 @@ Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_USER_AUTHENTICATION + Tcl_SetVar2(interp, "sqlite_options", "userauth", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "userauth", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_MULTIPLEX_EXT_OVWR Tcl_SetVar2(interp, "sqlite_options", "multiplex_ext_overwrite", "1", TCL_GLOBAL_ONLY); #else From d39c40ff5e89601a242f004faa45735e80275fcb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 00:27:53 +0000 Subject: [PATCH 15/30] Reorder parameters on the sqlite3_user_*() interfaces for consistency. Add the first TCL test cases. FossilOrigin-Name: 2f6d8f32eef526b5912f42ab467e3c7812480d8b --- ext/userauth/sqlite3userauth.h | 12 +-- ext/userauth/user-auth.txt | 27 ++++--- ext/userauth/userauth.c | 14 ++-- manifest | 21 +++--- manifest.uuid | 2 +- src/shell.c | 17 +++-- src/test1.c | 133 +++++++++++++++++++++++++++++++++ test/userauth01.test | 74 ++++++++++++++++++ 8 files changed, 257 insertions(+), 43 deletions(-) create mode 100644 test/userauth01.test diff --git a/ext/userauth/sqlite3userauth.h b/ext/userauth/sqlite3userauth.h index 9f95e9fe7a..619477cac9 100644 --- a/ext/userauth/sqlite3userauth.h +++ b/ext/userauth/sqlite3userauth.h @@ -36,8 +36,8 @@ int sqlite3_user_authenticate( sqlite3 *db, /* The database connection */ const char *zUsername, /* Username */ - int nPW, /* Number of bytes in aPW[] */ - const char *aPW /* Password or credentials */ + const char *aPW, /* Password or credentials */ + int nPW /* Number of bytes in aPW[] */ ); /* @@ -53,9 +53,9 @@ int sqlite3_user_authenticate( int sqlite3_user_add( sqlite3 *db, /* Database connection */ const char *zUsername, /* Username to be added */ - int isAdmin, /* True to give new user admin privilege */ + const char *aPW, /* Password or credentials */ int nPW, /* Number of bytes in aPW[] */ - const char *aPW /* Password or credentials */ + int isAdmin /* True to give new user admin privilege */ ); /* @@ -68,9 +68,9 @@ int sqlite3_user_add( int sqlite3_user_change( sqlite3 *db, /* Database connection */ const char *zUsername, /* Username to change */ - int isAdmin, /* Modified admin privilege for the user */ + const char *aPW, /* New password or credentials */ int nPW, /* Number of bytes in aPW[] */ - const char *aPW /* Modified password or credentials */ + int isAdmin /* Modified admin privilege for the user */ ); /* diff --git a/ext/userauth/user-auth.txt b/ext/userauth/user-auth.txt index dd49dfcfb7..85083d01c2 100644 --- a/ext/userauth/user-auth.txt +++ b/ext/userauth/user-auth.txt @@ -7,24 +7,24 @@ activated: int sqlite3_user_authenticate( sqlite3 *db, /* The database connection */ const char *zUsername, /* Username */ - int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Password or credentials */ + const char *aPW, /* Password or credentials */ + int nPW /* Number of bytes in aPW[] */ ); int sqlite3_user_add( sqlite3 *db, /* Database connection */ const char *zUsername, /* Username to be added */ - int isAdmin, /* True to give new user admin privilege */ + const char *aPW, /* Password or credentials */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Password or credentials */ + int isAdmin /* True to give new user admin privilege */ ); int sqlite3_user_change( sqlite3 *db, /* Database connection */ const char *zUsername, /* Username to change */ - int isAdmin, /* Modified admin privilege for the user */ + const void *aPW, /* Modified password or credentials */ int nPW, /* Number of bytes in aPW[] */ - const void *aPW /* Modified password or credentials */ + int isAdmin /* Modified admin privilege for the user */ ); int sqlite3_user_delete( @@ -71,12 +71,15 @@ check fails, then the ATTACH-ed database is unreadable [1g]. The sqlite3_user_add() interface can be used (by an admin user only) to create a new user. When called on a no-authentication-required -database, this routine converts the database into an authentication- -required database [3], automatically makes the added user an -administrator [1b], and logs in the current connection as that user [1a]. -The sqlite3_user_add() interface only works for the "main" database, not -for any ATTACH-ed databases. Any call to sqlite3_user_add() by a -non-admin user results in an error. +database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine +converts the database into an authentication-required database and +logs the database connection D in using user U with password P,N. +To convert a no-authentication-required database into an authentication- +required database, the isAdmin parameter must be true. If +sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required +database and A is false, then the call fails with an SQLITE_AUTH error. + +Any call to sqlite3_user_add() by a non-admin user results in an error. Hence, to create a new, unencrypted, authentication-required database, the call sequence is: diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 5e00c5cfb2..343e49e6ff 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -177,8 +177,8 @@ void sqlite3CryptFunc( int sqlite3_user_authenticate( sqlite3 *db, /* The database connection */ const char *zUsername, /* Username */ - int nPW, /* Number of bytes in aPW[] */ - const char *zPW /* Password or credentials */ + const char *zPW, /* Password or credentials */ + int nPW /* Number of bytes in aPW[] */ ){ int rc; u8 authLevel = UAUTH_Fail; @@ -217,9 +217,9 @@ int sqlite3_user_authenticate( int sqlite3_user_add( sqlite3 *db, /* Database connection */ const char *zUsername, /* Username to be added */ - int isAdmin, /* True to give new user admin privilege */ + const char *aPW, /* Password or credentials */ int nPW, /* Number of bytes in aPW[] */ - const char *aPW /* Password or credentials */ + int isAdmin /* True to give new user admin privilege */ ){ sqlite3_stmt *pStmt; int rc; @@ -248,7 +248,7 @@ int sqlite3_user_add( if( rc ) return rc; if( db->auth.zAuthUser==0 ){ assert( isAdmin!=0 ); - sqlite3_user_authenticate(db, zUsername, nPW, aPW); + sqlite3_user_authenticate(db, zUsername, aPW, nPW); } return SQLITE_OK; } @@ -263,9 +263,9 @@ int sqlite3_user_add( int sqlite3_user_change( sqlite3 *db, /* Database connection */ const char *zUsername, /* Username to change */ - int isAdmin, /* Modified admin privilege for the user */ + const char *aPW, /* Modified password or credentials */ int nPW, /* Number of bytes in aPW[] */ - const char *aPW /* Modified password or credentials */ + int isAdmin /* Modified admin privilege for the user */ ){ sqlite3_stmt *pStmt; if( db->auth.authLeveldb, azArg[2], (int)strlen(azArg[3]), azArg[3]); + rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], + (int)strlen(azArg[3])); if( rc ){ fprintf(stderr, "Authentication failed for user %s\n", azArg[2]); rc = 1; } }else if( strcmp(azArg[1],"add")==0 ){ if( nArg!=5 ){ - fprintf(stderr, "Usage: .user add USER ISADMIN PASSWORD\n"); + fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n"); rc = 1; goto meta_command_exit; } - rc = sqlite3_user_add(p->db, azArg[2], booleanValue(azArg[3]), - (int)strlen(azArg[4]), azArg[4]); + rc = sqlite3_user_add(p->db, azArg[2], + azArg[3], (int)strlen(azArg[3]), + booleanValue(azArg[4])); if( rc ){ fprintf(stderr, "User-Add failed: %d\n", rc); rc = 1; } }else if( strcmp(azArg[1],"edit")==0 ){ if( nArg!=5 ){ - fprintf(stderr, "Usage: .user edit USER ISADMIN PASSWORD\n"); + fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n"); rc = 1; goto meta_command_exit; } - rc = sqlite3_user_change(p->db, azArg[2], booleanValue(azArg[3]), - (int)strlen(azArg[4]), azArg[4]); + rc = sqlite3_user_change(p->db, azArg[2], + azArg[3], (int)strlen(azArg[3]), + booleanValue(azArg[4])); if( rc ){ fprintf(stderr, "User-Edit failed: %d\n", rc); rc = 1; diff --git a/src/test1.c b/src/test1.c index d050e683f4..62b575989d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -6497,6 +6497,132 @@ static int sorter_test_sort4_helper( } +#ifdef SQLITE_USER_AUTHENTICATION +#include "sqlite3userauth.h" +/* +** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD +*/ +static int test_user_authenticate( + ClientData clientData, /* Unused */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + char *zUser = 0; + char *zPasswd = 0; + int nPasswd = 0; + sqlite3 *db; + int rc; + + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + zUser = Tcl_GetString(objv[2]); + zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); + rc = sqlite3_user_authenticate(db, zUser, zPasswd, nPasswd); + Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); + return TCL_OK; +} +#endif /* SQLITE_USER_AUTHENTICATION */ + +#ifdef SQLITE_USER_AUTHENTICATION +/* +** tclcmd: sqlite3_user_add DB USERNAME PASSWORD ISADMIN +*/ +static int test_user_add( + ClientData clientData, /* Unused */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + char *zUser = 0; + char *zPasswd = 0; + int nPasswd = 0; + int isAdmin = 0; + sqlite3 *db; + int rc; + + if( objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + zUser = Tcl_GetString(objv[2]); + zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); + Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); + rc = sqlite3_user_add(db, zUser, zPasswd, nPasswd, isAdmin); + Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); + return TCL_OK; +} +#endif /* SQLITE_USER_AUTHENTICATION */ + +#ifdef SQLITE_USER_AUTHENTICATION +/* +** tclcmd: sqlite3_user_change DB USERNAME PASSWORD ISADMIN +*/ +static int test_user_change( + ClientData clientData, /* Unused */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + char *zUser = 0; + char *zPasswd = 0; + int nPasswd = 0; + int isAdmin = 0; + sqlite3 *db; + int rc; + + if( objc!=5 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + zUser = Tcl_GetString(objv[2]); + zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); + Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin); + rc = sqlite3_user_change(db, zUser, zPasswd, nPasswd, isAdmin); + Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); + return TCL_OK; +} +#endif /* SQLITE_USER_AUTHENTICATION */ + +#ifdef SQLITE_USER_AUTHENTICATION +/* +** tclcmd: sqlite3_user_delete DB USERNAME +*/ +static int test_user_delete( + ClientData clientData, /* Unused */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + char *zUser = 0; + sqlite3 *db; + int rc; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ + return TCL_ERROR; + } + zUser = Tcl_GetString(objv[2]); + rc = sqlite3_user_delete(db, zUser); + Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); + return TCL_OK; +} +#endif /* SQLITE_USER_AUTHENTICATION */ + /* ** Register commands with the TCL interpreter. */ @@ -6734,6 +6860,13 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "load_static_extension", tclLoadStaticExtensionCmd }, { "sorter_test_fakeheap", sorter_test_fakeheap }, { "sorter_test_sort4_helper", sorter_test_sort4_helper }, +#ifdef SQLITE_USER_AUTHENTICATION + { "sqlite3_user_authenticate", test_user_authenticate, 0 }, + { "sqlite3_user_add", test_user_add, 0 }, + { "sqlite3_user_change", test_user_change, 0 }, + { "sqlite3_user_delete", test_user_delete, 0 }, +#endif + }; static int bitmask_size = sizeof(Bitmask)*8; int i; diff --git a/test/userauth01.test b/test/userauth01.test new file mode 100644 index 0000000000..60e617e3ba --- /dev/null +++ b/test/userauth01.test @@ -0,0 +1,74 @@ +# 2014-09-10 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests of the SQLITE_USER_AUTHENTICATION extension. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix userauth01 + +ifcapable !userauth { + finish_test + return +} + +# Create a no-authentication-required database +# +do_execsql_test userauth01-1.0 { + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1),(2.5),('three'),(x'4444'),(NULL); + SELECT quote(x) FROM t1 ORDER BY x; + SELECT name FROM sqlite_master; +} {NULL 1 2.5 'three' X'4444' t1} + +# Calling sqlite3_user_authenticate() on a no-authentication-required +# database connection is a harmless no-op. +# +do_test userauth01-1.1 { + sqlite3_user_authenticate db alice pw-4-alice + execsql { + SELECT quote(x) FROM t1 ORDER BY x; + SELECT name FROM sqlite_master; + } +} {NULL 1 2.5 'three' X'4444' t1} + +# If sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required +# database and A is false, then the call fails with an SQLITE_AUTH error. +# +do_test userauth01-1.2 { + sqlite3_user_add db bob pw-4-bob 0 +} {SQLITE_AUTH} +do_test userauth01-1.3 { + execsql { + SELECT quote(x) FROM t1 ORDER BY x; + SELECT name FROM sqlite_master; + } +} {NULL 1 2.5 'three' X'4444' t1} + +# When called on a no-authentication-required +# database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine +# converts the database into an authentication-required database and +# logs the database connection D in using user U with password P,N. +# +do_test userauth01-1.4 { + sqlite3_user_add db alice pw-4-alice 1 +} {SQLITE_OK} +do_test userauth01-1.5 { + execsql { + SELECT quote(x) FROM t1 ORDER BY x; + SELECT uname, isadmin FROM sqlite_user ORDER BY uname; + SELECT name FROM sqlite_master ORDER BY name; + } +} {NULL 1 2.5 'three' X'4444' alice 1 sqlite_user t1} + + +finish_test From 32c6a48b5ec977fc849833f9c340b85893103074 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 13:44:52 +0000 Subject: [PATCH 16/30] Add support for the extra parameter on the sqlite3_set_authorizer() callback and support for failing an ATTACH with an authentication-required database using bad credentials. The extension is now feature complete, but much testing and bug-fixing remains. FossilOrigin-Name: 596e728b0eb19a34c888e33d4d37978ca2bf1e00 --- ext/userauth/user-auth.txt | 43 +++--- manifest | 40 +++--- manifest.uuid | 2 +- src/attach.c | 9 ++ src/auth.c | 14 +- src/build.c | 2 +- src/prepare.c | 2 +- src/sqliteInt.h | 15 +- src/tclsqlite.c | 11 +- test/auth.test | 274 ++++++++++++++++++------------------- test/auth2.test | 4 +- test/auth3.test | 2 +- test/fkey2.test | 2 +- test/fts4aa.test | 2 +- test/savepoint.test | 4 +- test/vtab3.test | 2 +- test/without_rowid3.test | 2 +- 17 files changed, 238 insertions(+), 192 deletions(-) diff --git a/ext/userauth/user-auth.txt b/ext/userauth/user-auth.txt index 85083d01c2..8b64617c36 100644 --- a/ext/userauth/user-auth.txt +++ b/ext/userauth/user-auth.txt @@ -1,5 +1,12 @@ -Activate the user authentication logic by compiling SQLite with -the -DSQLITE_USER_AUTHENTICATION compile-time option. +Activate the user authentication logic by including the +ext/userauth/userauth.c source code file in the build and +adding the -DSQLITE_USER_AUTHENTICATION compile-time option. +The ext/userauth/sqlite3userauth.h header file is available to +applications to define the interface. + +When using the SQLite amalgamation, it is sufficient to append +the ext/userauth/userauth.c source file onto the end of the +amalgamation. The following new APIs are available when user authentication is activated: @@ -31,12 +38,16 @@ activated: sqlite3 *db, /* Database connection */ const char *zUsername /* Username to remove */ ); - + +With this extension, a database can be marked as requiring authentication. +By default a database does not require authentication. + The sqlite3_open(), sqlite3_open16(), and sqlite3_open_v2() interfaces work as before: they open a new database connection. However, if the -database being opened requires authentication, then the database -connection will be unusable until after sqlite3_user_authenticate() -has been called successfully [1c]. The sqlite3_user_authenticate() call +database being opened requires authentication, then attempts to prepare +SQL statements (using sqlite3_prepare_v2(), for example) will fail +with an SQLITE_AUTH error until after sqlite3_user_authenticate() +has been called successfully. The sqlite3_user_authenticate() call will return SQLITE_OK if the authentication credentials are accepted and SQLITE_ERROR if not. @@ -67,13 +78,13 @@ connection is treated as if it was authenticated as an admin user. When ATTACH-ing new database files to a connection, each newly attached database that is an authentication-required database is checked using the same username and password as supplied to the main database. If that -check fails, then the ATTACH-ed database is unreadable [1g]. +check fails, then the ATTACH command fails with an SQLITE_AUTH error. The sqlite3_user_add() interface can be used (by an admin user only) to create a new user. When called on a no-authentication-required database and when A is true, the sqlite3_user_add(D,U,P,N,A) routine converts the database into an authentication-required database and -logs the database connection D in using user U with password P,N. +logs in the database connection D as user U with password P,N. To convert a no-authentication-required database into an authentication- required database, the isAdmin parameter must be true. If sqlite3_user_add(D,U,P,N,A) is called on a no-authentication-required @@ -98,17 +109,17 @@ The sqlite3_user_delete() interface can be used (by an admin user only) to delete a user. The currently logged-in user cannot be deleted, which guarantees that there is always an admin user and hence that the database cannot be converted into a no-authentication-required -database [3]. +database. The sqlite3_user_change() interface can be used to change a users login credentials or admin privilege. Any user can change their own -login credentials [1b]. Only an admin user can change another users login +password. Only an admin user can change another users login credentials or admin privilege setting. No user may change their own admin privilege setting. The sqlite3_set_authorizer() callback is modified to take a 7th parameter which is the username of the currently logged in user, or NULL for a -no-authentication-required database [1d]. +no-authentication-required database. ----------------------------------------------------------------------------- Implementation notes: @@ -133,8 +144,8 @@ The sqlite_user.pw field is encoded by a built-in SQL function "sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument is the plaintext password supplied to the sqlite3_user_authenticate() interface. The second argument is the sqlite_user.pw value and is supplied -so that the function can extra the "salt" used by the password encoder. -the result of sqlite_crypt(X,Y) is another blob which is the value that +so that the function can extract the "salt" used by the password encoder. +The result of sqlite_crypt(X,Y) is another blob which is the value that ends up being stored in sqlite_user.pw. To verify credentials X supplied by the sqlite3_user_authenticate() routine, SQLite runs: @@ -145,9 +156,9 @@ password X, sqlite_crypt(X,NULL) is run. A new random salt is selected when the second argument is NULL. The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher -which prevents passwords from being revealed by search the raw database -for ASCII text, but is otherwise trivally broken. To truly secure the -passwords, the database should be encrypted using the SQLite Encryption +which prevents passwords from being revealed by searching the raw database +for ASCII text, but is otherwise trivally broken. For better password +security, the database should be encrypted using the SQLite Encryption Extension or similar technology. Or, the application can use the sqlite3_create_function() interface to provide an alternative implementation of sqlite_crypt() that computes a stronger password hash, diff --git a/manifest b/manifest index ad8259c2fc..12328063d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reorder\sparameters\son\sthe\ssqlite3_user_*()\sinterfaces\sfor\sconsistency.\nAdd\sthe\sfirst\sTCL\stest\scases. -D 2014-09-11T00:27:53.371 +C Add\ssupport\sfor\sthe\sextra\sparameter\son\sthe\ssqlite3_set_authorizer()\scallback\nand\ssupport\sfor\sfailing\san\sATTACH\swith\san\sauthentication-required\sdatabase\nusing\sbad\scredentials.\s\sThe\sextension\sis\snow\sfeature\scomplete,\sbut\smuch\ntesting\sand\sbug-fixing\sremains. +D 2014-09-11T13:44:52.150 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -145,7 +145,7 @@ F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 -F ext/userauth/user-auth.txt a0340e6219f0b70fde57502c8f6b1c5fdb23023e +F ext/userauth/user-auth.txt 527aaec593ae34dcaf543324623c8351a5d33d3f F ext/userauth/userauth.c a66cd3abcc3b2c10b3999ab49f900d561e8ddd33 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 @@ -166,15 +166,15 @@ F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb F src/analyze.c 79383a54fee3b7f1fb03dd4c8c8115583f506de5 -F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 -F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 +F src/attach.c cc9b30041dfcd24be0a47986c87c384515c54449 +F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc -F src/build.c 3a61555d469de2e0f5bcd1ac4d58a2a19ab093d5 +F src/build.c 4c7aac1ddda782c6f1cad84aeabec6e8d0be7495 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/ctime.c 16cd19215d9fd849ee2b7509b092f2e0bbd6a958 @@ -221,7 +221,7 @@ F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3b7b1a5e90804006f44c65464c7032ee6a1d24e3 -F src/prepare.c 10dd9833d7aa992baf84b8640224853576119d84 +F src/prepare.c f82c009a763e739c6bdf02a270ccfda9e54f783c F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb @@ -231,11 +231,11 @@ F src/shell.c 7d26b6526fb9daab994265446b751fb86fd9d675 F src/sqlite.h.in 577876beef2264a0b031c0d744c81855983088f9 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 1f40357fb9b12a80c5a3b2b109fd249b009213d4 -F src/sqliteInt.h fdc23ef0c5475888d0e532204a7451507ce17206 +F src/sqliteInt.h cb44c24e5c5d52f33bb9e78bfcc9c703b1d178c4 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 4e28a53e66bad8d014a510ef0205f5497c712b08 -F src/tclsqlite.c 8d6d6833c0053f0b3b1aeb1c5c7a7eeff0ad4d3f +F src/tclsqlite.c c67d310c833046cccc192125d64ad422ab882684 F src/test1.c 523cd70ded28db71af9a30ec184cbe0957de9575 F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -336,9 +336,9 @@ F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27 F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 -F test/auth.test 5bdf154eb28c0e4bbc0473f335858c0d96171768 -F test/auth2.test c3b415b76c033bedb81292118fb7c01f5f10cbcd -F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 +F test/auth.test 855233ef26eb3601b6886567ea4e326c72959360 +F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa +F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 F test/autoindex1.test 762ff3f8e25d852aae55c6462ca166a80c0cde61 F test/autoindex2.test 60d2fc6f38364308ce73a9beb01b47ded38697de @@ -479,7 +479,7 @@ F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7 F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146 F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b -F test/fkey2.test 32ca728bcb854feed72d1406ea375fe423eebff2 +F test/fkey2.test 1db212cda86b0d3ce72714001f7b6381c321341c F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 8a1fde4e7721ae00b05b3178888833726ca2df8d @@ -577,7 +577,7 @@ F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test c551043de056b0b1582a54e878991f57bad074bc F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e -F test/fts4aa.test 0c3152322c7f0b548cc942ad763eaba0da87ccca +F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb F test/fts4check.test 74d77f6cdb768ac49df5afda575cef14ae3d239a F test/fts4content.test 2e7252557d6d24afa101d9ba1de710d6140e6d06 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 @@ -785,7 +785,7 @@ F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test b78b30afb9537a73788ca1233a23a32190a3bb1f F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 -F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b +F test/savepoint.test 51d3900dc071a7c2ad4248578a5925631b476313 F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7 F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 @@ -1068,7 +1068,7 @@ F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9 F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6 F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d -F test/vtab3.test baad99fd27217f5d6db10660522e0b7192446de1 +F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391 F test/vtab6.test 5f5380c425e52993560ab4763db4f826d2ba7b09 @@ -1140,7 +1140,7 @@ F test/with2.test ee227a663586aa09771cafd4fa269c5217eaf775 F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 F test/without_rowid1.test 7862e605753c8d25329f665fa09072e842183151 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 -F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 +F test/without_rowid3.test 1081aabf60a1e1123b7f9a8f6ae19954351843b0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test b4a639a367f04d382d20e8f44fc1be4f2d57d107 F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4eaaa7fa87aa912d24f8b35440ab60310dc08310 -R b62ab47ef5a1f118b5c6bf446676036b +P 2f6d8f32eef526b5912f42ab467e3c7812480d8b +R 8b68610f4a9d73b92fb9d68a3359baf2 U drh -Z 388f9ca2f5e0d91d315989cc617a17a1 +Z 6a1c7f3384e27f9ad12e8ea277382ab2 diff --git a/manifest.uuid b/manifest.uuid index 2679d57ef9..1b3da62f36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f6d8f32eef526b5912f42ab467e3c7812480d8b \ No newline at end of file +596e728b0eb19a34c888e33d4d37978ca2bf1e00 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 89050fd9dc..5763e631ad 100644 --- a/src/attach.c +++ b/src/attach.c @@ -207,6 +207,15 @@ static void attachFunc( rc = sqlite3Init(db, &zErrDyn); sqlite3BtreeLeaveAll(db); } +#ifdef SQLITE_USER_AUTHENTICATION + if( rc==SQLITE_OK ){ + u8 newAuth = 0; + rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); + if( newAuthauth.authLevel ){ + rc = SQLITE_AUTH; + } + } +#endif if( rc ){ int iDb = db->nDb - 1; assert( iDb>=2 ); diff --git a/src/auth.c b/src/auth.c index d38bb836a7..1680c9a7c2 100644 --- a/src/auth.c +++ b/src/auth.c @@ -73,7 +73,7 @@ int sqlite3_set_authorizer( void *pArg ){ sqlite3_mutex_enter(db->mutex); - db->xAuth = xAuth; + db->xAuth = (sqlite3_xauth)xAuth; db->pAuthArg = pArg; sqlite3ExpirePreparedStatements(db); sqlite3_mutex_leave(db->mutex); @@ -108,7 +108,11 @@ int sqlite3AuthReadCol( char *zDb = db->aDb[iDb].zName; /* Name of attached database */ int rc; /* Auth callback return code */ - rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext +#ifdef SQLITE_USER_AUTHENTICATION + ,db->auth.zAuthUser +#endif + ); if( rc==SQLITE_DENY ){ if( db->nDb>2 || iDb!=0 ){ sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); @@ -208,7 +212,11 @@ int sqlite3AuthCheck( if( db->xAuth==0 ){ return SQLITE_OK; } - rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext); + rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext +#ifdef SQLITE_USER_AUTHENTICATION + ,db->auth.zAuthUser +#endif + ); if( rc==SQLITE_DENY ){ sqlite3ErrorMsg(pParse, "not authorized"); pParse->rc = SQLITE_AUTH; diff --git a/src/build.c b/src/build.c index f745164e54..c94c5a1310 100644 --- a/src/build.c +++ b/src/build.c @@ -2075,7 +2075,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); + sqlite3_xauth xAuth; /* Saved xAuth pointer */ assert( pTable ); diff --git a/src/prepare.c b/src/prepare.c index c6752548ff..c57fda0026 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -328,7 +328,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ db->aDb[iDb].zName, zMasterName); #ifndef SQLITE_OMIT_AUTHORIZATION { - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); + sqlite3_xauth xAuth; xAuth = db->xAuth; db->xAuth = 0; #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9ef4e36208..a9f2001457 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1012,9 +1012,19 @@ int sqlite3UserAuthTable(const char*); int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); - #endif /* SQLITE_USER_AUTHENTICATION */ +/* +** typedef for the authorization callback function. +*/ +#ifdef SQLITE_USER_AUTHENTICATION + typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*, const char*); +#else + typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); +#endif + /* ** Each database connection is an instance of the following structure. @@ -1083,8 +1093,7 @@ struct sqlite3 { } u1; Lookaside lookaside; /* Lookaside malloc configuration */ #ifndef SQLITE_OMIT_AUTHORIZATION - int (*xAuth)(void*,int,const char*,const char*,const char*,const char*); - /* Access authorization function */ + sqlite3_xauth xAuth; /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 945fd95982..756d0daa5a 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -872,6 +872,9 @@ static int auth_callback( const char *zArg2, const char *zArg3, const char *zArg4 +#ifdef SQLITE_USER_AUTHENTICATION + ,const char *zArg5 +#endif ){ const char *zCode; Tcl_DString str; @@ -924,6 +927,9 @@ static int auth_callback( Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); +#ifdef SQLITE_USER_AUTHENTICATION + Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); +#endif rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); Tcl_DStringFree(&str); zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; @@ -1700,8 +1706,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ pDb->zAuth = 0; } if( pDb->zAuth ){ + typedef int (*sqlite3_auth_cb)( + void*,int,const char*,const char*, + const char*,const char*); pDb->interp = interp; - sqlite3_set_authorizer(pDb->db, auth_callback, pDb); + sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb); }else{ sqlite3_set_authorizer(pDb->db, 0, 0); } diff --git a/test/auth.test b/test/auth.test index 43e53ef2e3..f3c2fa79e8 100644 --- a/test/auth.test +++ b/test/auth.test @@ -36,7 +36,7 @@ proc_real proc {name arguments script} { do_test auth-1.1.1 { db close set ::DB [sqlite3 db test.db] - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -61,7 +61,7 @@ do_test auth-1.2 { execsql {SELECT name FROM sqlite_master} } {} do_test auth-1.3.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -82,7 +82,7 @@ do_test auth-1.4 { ifcapable tempdb { do_test auth-1.5 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -94,7 +94,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {} do_test auth-1.7.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -112,7 +112,7 @@ ifcapable tempdb { } do_test auth-1.9 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -124,7 +124,7 @@ do_test auth-1.10 { execsql {SELECT name FROM sqlite_master} } {} do_test auth-1.11 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -139,7 +139,7 @@ do_test auth-1.12 { ifcapable tempdb { do_test auth-1.13 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -151,7 +151,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {} do_test auth-1.15 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -165,7 +165,7 @@ ifcapable tempdb { } {} do_test auth-1.17 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -181,7 +181,7 @@ ifcapable tempdb { do_test auth-1.19.1 { set ::authargs {} - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -198,7 +198,7 @@ do_test auth-1.20 { } {t2} do_test auth-1.21.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -214,7 +214,7 @@ do_test auth-1.22 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.23.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -232,7 +232,7 @@ do_test auth-1.24 { ifcapable tempdb { do_test auth-1.25 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -245,7 +245,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.27 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -260,7 +260,7 @@ ifcapable tempdb { } do_test auth-1.29 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="t2"} { return SQLITE_DENY } @@ -272,7 +272,7 @@ do_test auth-1.30 { execsql {SELECT * FROM t2} } {} do_test auth-1.31 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="t2"} { return SQLITE_IGNORE } @@ -284,7 +284,7 @@ do_test auth-1.32 { execsql {SELECT * FROM t2} } {} do_test auth-1.33 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="t1"} { return SQLITE_IGNORE } @@ -297,7 +297,7 @@ do_test auth-1.34 { } {1 2 3} do_test auth-1.35.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} { return SQLITE_DENY } @@ -313,7 +313,7 @@ ifcapable attach { execsql {DETACH DATABASE two} } do_test auth-1.36 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} { return SQLITE_IGNORE } @@ -322,7 +322,7 @@ do_test auth-1.36 { catchsql {SELECT * FROM t2} } {0 {1 {} 3}} do_test auth-1.37 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} { return SQLITE_IGNORE } @@ -331,7 +331,7 @@ do_test auth-1.37 { catchsql {SELECT * FROM t2 WHERE b=2} } {0 {}} do_test auth-1.38 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="a"} { return SQLITE_IGNORE } @@ -340,7 +340,7 @@ do_test auth-1.38 { catchsql {SELECT * FROM t2 WHERE b=2} } {0 {{} 2 3}} do_test auth-1.39 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} { return SQLITE_IGNORE } @@ -349,7 +349,7 @@ do_test auth-1.39 { catchsql {SELECT * FROM t2 WHERE b IS NULL} } {0 {1 {} 3}} do_test auth-1.40 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="b"} { return SQLITE_DENY } @@ -359,7 +359,7 @@ do_test auth-1.40 { } {1 {access to t2.b is prohibited}} do_test auth-1.41 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_UPDATE" && $arg1=="t2" && $arg2=="b"} { return SQLITE_DENY } @@ -371,7 +371,7 @@ do_test auth-1.42 { execsql {SELECT * FROM t2} } {11 2 3} do_test auth-1.43 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_UPDATE" && $arg1=="t2" && $arg2=="b"} { return SQLITE_DENY } @@ -383,7 +383,7 @@ do_test auth-1.44 { execsql {SELECT * FROM t2} } {11 2 3} do_test auth-1.45 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_UPDATE" && $arg1=="t2" && $arg2=="b"} { return SQLITE_IGNORE } @@ -396,7 +396,7 @@ do_test auth-1.46 { } {11 2 33} do_test auth-1.47 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="t2"} { return SQLITE_DENY } @@ -408,7 +408,7 @@ do_test auth-1.48 { execsql {SELECT * FROM t2} } {11 2 33} do_test auth-1.49 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="t2"} { return SQLITE_IGNORE } @@ -424,7 +424,7 @@ do_test auth-1.50.2 { } {} do_test auth-1.51 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_SELECT"} { return SQLITE_DENY } @@ -433,7 +433,7 @@ do_test auth-1.51 { catchsql {SELECT * FROM t2} } {1 {not authorized}} do_test auth-1.52 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_SELECT"} { return SQLITE_IGNORE } @@ -442,7 +442,7 @@ do_test auth-1.52 { catchsql {SELECT * FROM t2} } {0 {}} do_test auth-1.53 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_SELECT"} { return SQLITE_OK } @@ -462,7 +462,7 @@ do_test auth-1.55 { } {11 2 33 7 8 9} do_test auth-1.63 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -474,7 +474,7 @@ do_test auth-1.64 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.65 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="t2"} { return SQLITE_DENY } @@ -488,7 +488,7 @@ do_test auth-1.66 { ifcapable tempdb { do_test auth-1.67 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -500,7 +500,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.69 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="t1"} { return SQLITE_DENY } @@ -514,7 +514,7 @@ ifcapable tempdb { } do_test auth-1.71 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -526,7 +526,7 @@ do_test auth-1.72 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.73 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="t2"} { return SQLITE_IGNORE } @@ -540,7 +540,7 @@ do_test auth-1.74 { ifcapable tempdb { do_test auth-1.75 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -552,7 +552,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.77 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="t1"} { return SQLITE_IGNORE } @@ -569,7 +569,7 @@ ifcapable tempdb { # Omit these if the library was compiled with views omitted. ifcapable view { do_test auth-1.79 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -585,7 +585,7 @@ do_test auth-1.81 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.82 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -603,7 +603,7 @@ do_test auth-1.84 { ifcapable tempdb { do_test auth-1.85 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -619,7 +619,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.88 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -637,7 +637,7 @@ ifcapable tempdb { } do_test auth-1.91 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -649,7 +649,7 @@ do_test auth-1.92 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.93 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -663,7 +663,7 @@ do_test auth-1.94 { ifcapable tempdb { do_test auth-1.95 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -675,7 +675,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.97 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -689,7 +689,7 @@ ifcapable tempdb { } do_test auth-1.99 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -704,7 +704,7 @@ do_test auth-1.100 { execsql {SELECT name FROM sqlite_master} } {t2 v2} do_test auth-1.101 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -720,7 +720,7 @@ do_test auth-1.103 { execsql {SELECT name FROM sqlite_master} } {t2 v2} do_test auth-1.104 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -732,7 +732,7 @@ do_test auth-1.105 { execsql {SELECT name FROM sqlite_master} } {t2 v2} do_test auth-1.106 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -748,7 +748,7 @@ do_test auth-1.108 { execsql {SELECT name FROM sqlite_master} } {t2 v2} do_test auth-1.109 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -767,7 +767,7 @@ do_test auth-1.111 { ifcapable tempdb { do_test auth-1.112 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -782,7 +782,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 v1} do_test auth-1.114 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -798,7 +798,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 v1} do_test auth-1.117 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -810,7 +810,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 v1} do_test auth-1.119 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -826,7 +826,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 v1} do_test auth-1.122 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_VIEW"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -849,7 +849,7 @@ ifcapable tempdb { # ifcapable trigger&&tempdb { do_test auth-1.125 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -869,7 +869,7 @@ do_test auth-1.127 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.128 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -885,7 +885,7 @@ do_test auth-1.129 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.130 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -905,7 +905,7 @@ do_test auth-1.132 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.133 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -921,7 +921,7 @@ do_test auth-1.134 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.135 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -944,7 +944,7 @@ do_test auth-1.136.2 { } } {r2} do_test auth-1.136.3 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { lappend ::authargs $code $arg1 $arg2 $arg3 $arg4 return SQLITE_OK } @@ -963,7 +963,7 @@ do_test auth-1.137 { execsql {SELECT name FROM sqlite_master} } {t2 tx r2} do_test auth-1.138 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -983,7 +983,7 @@ do_test auth-1.140 { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.141 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -999,7 +999,7 @@ do_test auth-1.142 { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.143 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1019,7 +1019,7 @@ do_test auth-1.145 { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.146 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -1035,7 +1035,7 @@ do_test auth-1.147 { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.148 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1056,7 +1056,7 @@ do_test auth-1.150 { } {t1 r1} do_test auth-1.151 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -1068,7 +1068,7 @@ do_test auth-1.152 { execsql {SELECT name FROM sqlite_master} } {t2 tx r2} do_test auth-1.153 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1084,7 +1084,7 @@ do_test auth-1.155 { execsql {SELECT name FROM sqlite_master} } {t2 tx r2} do_test auth-1.156 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -1096,7 +1096,7 @@ do_test auth-1.157 { execsql {SELECT name FROM sqlite_master} } {t2 tx r2} do_test auth-1.158 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1112,7 +1112,7 @@ do_test auth-1.160 { execsql {SELECT name FROM sqlite_master} } {t2 tx r2} do_test auth-1.161 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1133,7 +1133,7 @@ do_test auth-1.163 { } {t2} do_test auth-1.164 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -1145,7 +1145,7 @@ do_test auth-1.165 { execsql {SELECT name FROM sqlite_temp_master} } {t1 r1} do_test auth-1.166 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1161,7 +1161,7 @@ do_test auth-1.168 { execsql {SELECT name FROM sqlite_temp_master} } {t1 r1} do_test auth-1.169 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -1173,7 +1173,7 @@ do_test auth-1.170 { execsql {SELECT name FROM sqlite_temp_master} } {t1 r1} do_test auth-1.171 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1189,7 +1189,7 @@ do_test auth-1.173 { execsql {SELECT name FROM sqlite_temp_master} } {t1 r1} do_test auth-1.174 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_TRIGGER"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1207,7 +1207,7 @@ do_test auth-1.176 { } ;# ifcapable trigger do_test auth-1.177 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1223,7 +1223,7 @@ do_test auth-1.179 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.180 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -1235,7 +1235,7 @@ do_test auth-1.181 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.182 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1251,7 +1251,7 @@ do_test auth-1.184 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.185 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -1263,7 +1263,7 @@ do_test auth-1.186 { execsql {SELECT name FROM sqlite_master} } {t2} do_test auth-1.187 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1281,7 +1281,7 @@ do_test auth-1.189 { ifcapable tempdb { do_test auth-1.190 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1297,7 +1297,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.193 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -1309,7 +1309,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.195 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1325,7 +1325,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.198 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_INSERT" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -1337,7 +1337,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1} do_test auth-1.200 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_CREATE_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1355,7 +1355,7 @@ ifcapable tempdb { } do_test auth-1.203 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_DENY } @@ -1367,7 +1367,7 @@ do_test auth-1.204 { execsql {SELECT name FROM sqlite_master} } {t2 i2} do_test auth-1.205 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1383,7 +1383,7 @@ do_test auth-1.207 { execsql {SELECT name FROM sqlite_master} } {t2 i2} do_test auth-1.208 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_master"} { return SQLITE_IGNORE } @@ -1395,7 +1395,7 @@ do_test auth-1.209 { execsql {SELECT name FROM sqlite_master} } {t2 i2} do_test auth-1.210 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1411,7 +1411,7 @@ do_test auth-1.212 { execsql {SELECT name FROM sqlite_master} } {t2 i2} do_test auth-1.213 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1429,7 +1429,7 @@ do_test auth-1.215 { ifcapable tempdb { do_test auth-1.216 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_DENY } @@ -1441,7 +1441,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 i1} do_test auth-1.218 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1457,7 +1457,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 i1} do_test auth-1.221 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE" && $arg1=="sqlite_temp_master"} { return SQLITE_IGNORE } @@ -1469,7 +1469,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 i1} do_test auth-1.223 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1485,7 +1485,7 @@ ifcapable tempdb { execsql {SELECT name FROM sqlite_temp_master} } {t1 i1} do_test auth-1.226 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DROP_TEMP_INDEX"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1503,7 +1503,7 @@ ifcapable tempdb { } do_test auth-1.229 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_PRAGMA"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1519,7 +1519,7 @@ do_test auth-1.231 { execsql2 {SELECT a FROM t2} } {a 11 a 7} do_test auth-1.232 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_PRAGMA"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1535,7 +1535,7 @@ do_test auth-1.234 { execsql2 {SELECT a FROM t2} } {a 11 a 7} do_test auth-1.235 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_PRAGMA"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1548,7 +1548,7 @@ do_test auth-1.236 { execsql2 {SELECT a FROM t2} } {t2.a 11 t2.a 7} do_test auth-1.237 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_PRAGMA"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1565,7 +1565,7 @@ do_test auth-1.239 { } {a 11 a 7} do_test auth-1.240 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_TRANSACTION"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1578,7 +1578,7 @@ do_test auth-1.241 { set ::authargs } {BEGIN {} {} {}} do_test auth-1.242 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_TRANSACTION" && $arg1!="BEGIN"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1618,7 +1618,7 @@ do_test auth-1.250 { ifcapable attach { do_test auth-1.251 { db authorizer ::auth - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ATTACH"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] } @@ -1644,7 +1644,7 @@ ifcapable attach { } {{} {} {} {}} do_test auth-1.253 { catchsql {DETACH DATABASE test1} - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ATTACH"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1660,7 +1660,7 @@ ifcapable attach { } {} do_test auth-1.255 { catchsql {DETACH DATABASE test1} - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ATTACH"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1675,7 +1675,7 @@ ifcapable attach { lindex [execsql {PRAGMA database_list}] 7 } {} do_test auth-1.257 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DETACH"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1692,7 +1692,7 @@ ifcapable attach { } {} do_test auth-1.259 { execsql {ATTACH DATABASE ':memory:' AS test1} - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DETACH"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1710,7 +1710,7 @@ ifcapable attach { } {test1} } ;# ifcapable schema_pragmas do_test auth-1.261 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DETACH"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1735,7 +1735,7 @@ ifcapable attach { ifcapable altertable { do_test auth-1.263 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1753,7 +1753,7 @@ ifcapable attach { set authargs } {temp t1 {} {}} do_test auth-1.266 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1771,7 +1771,7 @@ ifcapable attach { set authargs } {temp t1x {} {}} do_test auth-1.269 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1804,7 +1804,7 @@ db authorizer {} catchsql {ALTER TABLE t1x RENAME TO t1} db authorizer ::auth do_test auth-1.272 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -1822,7 +1822,7 @@ do_test auth-1.274 { set authargs } {main t2 {} {}} do_test auth-1.275 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -1840,7 +1840,7 @@ do_test auth-1.277 { set authargs } {main t2x {} {}} do_test auth-1.278 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -1867,7 +1867,7 @@ ifcapable reindex { proc auth {code args} { if {$code=="SQLITE_REINDEX"} { - set ::authargs [concat $::authargs $args] + set ::authargs [concat $::authargs [lrange $args 0 3]] } return SQLITE_OK } @@ -1950,7 +1950,7 @@ ifcapable tempdb { } {t3_idx2 {} temp {} t3_idx1 {} temp {} sqlite_autoindex_t3_1 {} temp {}} proc auth {code args} { if {$code=="SQLITE_REINDEX"} { - set ::authargs [concat $::authargs $args] + set ::authargs [concat $::authargs [lrange $args 0 3]] return SQLITE_DENY } return SQLITE_OK @@ -1973,7 +1973,7 @@ ifcapable tempdb { ifcapable analyze { proc auth {code args} { if {$code=="SQLITE_ANALYZE"} { - set ::authargs [concat $::authargs $args] + set ::authargs [concat $::authargs [lrange $args 0 3]] } return SQLITE_OK } @@ -2020,7 +2020,7 @@ ifcapable analyze { ifcapable {altertable} { do_test auth-1.300 { execsql {CREATE TABLE t5(x)} - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_OK @@ -2039,7 +2039,7 @@ ifcapable {altertable} { set authargs } {main t5 {} {}} do_test auth-1.303 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_IGNORE @@ -2058,7 +2058,7 @@ ifcapable {altertable} { set authargs } {main t5 {} {}} do_test auth-1.306 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_ALTER_TABLE"} { set ::authargs [list $arg1 $arg2 $arg3 $arg4] return SQLITE_DENY @@ -2082,7 +2082,7 @@ ifcapable {altertable} { ifcapable {cte} { do_test auth-1.310 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_RECURSIVE"} { return SQLITE_DENY } @@ -2117,7 +2117,7 @@ ifcapable {cte} { } ;# ifcapable cte do_test auth-2.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="x"} { return SQLITE_DENY } @@ -2137,7 +2137,7 @@ do_test auth-2.3 { catchsql {SELECT OID,y,z FROM t3} } {1 {access to t3.x is prohibited}} do_test auth-2.4 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="x"} { return SQLITE_IGNORE } @@ -2150,7 +2150,7 @@ do_test auth-2.5 { catchsql {SELECT rowid,y,z FROM t3} } {0 {{} 55 66}} do_test auth-2.6 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t3" && $arg2=="ROWID"} { return SQLITE_IGNORE } @@ -2162,7 +2162,7 @@ do_test auth-2.7 { catchsql {SELECT ROWID,y,z FROM t3} } {0 {44 55 66}} do_test auth-2.8 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="ROWID"} { return SQLITE_IGNORE } @@ -2181,7 +2181,7 @@ do_test auth-2.9.1 { # db cache flush - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="ROWID"} { return bogus } @@ -2193,7 +2193,7 @@ do_test auth-2.9.2 { db errorcode } {1} do_test auth-2.10 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_SELECT"} { return bogus } @@ -2202,7 +2202,7 @@ do_test auth-2.10 { catchsql {SELECT ROWID,b,c FROM t2} } {1 {authorizer malfunction}} do_test auth-2.11.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg2=="a"} { return SQLITE_IGNORE } @@ -2211,7 +2211,7 @@ do_test auth-2.11.1 { catchsql {SELECT * FROM t2, t3} } {0 {{} 2 33 44 55 66 {} 8 9 44 55 66}} do_test auth-2.11.2 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg2=="x"} { return SQLITE_IGNORE } @@ -2224,7 +2224,7 @@ do_test auth-2.11.2 { # ifcapable trigger { do_test auth-3.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { return SQLITE_OK } execsql { @@ -2237,7 +2237,7 @@ ifcapable trigger { } } {11 12 2 2 33 33 7 8 8 8 9 9} do_test auth-3.2 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_READ" && $arg1=="t2" && $arg2=="c"} { return SQLITE_IGNORE } @@ -2255,7 +2255,7 @@ ifcapable trigger { # ifcapable trigger { do_test auth-4.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { lappend ::authargs $code $arg1 $arg2 $arg3 $arg4 return SQLITE_OK } @@ -2340,7 +2340,7 @@ do_test auth-4.5 { # clause. # do_test auth-5.1 { - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { return SQLITE_OK } execsql { @@ -2393,7 +2393,7 @@ ifcapable trigger { } {} set ::authargs [list] proc auth {args} { - eval lappend ::authargs $args + eval lappend ::authargs [lrange $args 0 4] return SQLITE_OK } do_test auth-5.3.2 { @@ -2419,7 +2419,7 @@ do_test auth-6.1 { } {} set ::authargs [list] proc auth {args} { - eval lappend ::authargs $args + eval lappend ::authargs [lrange $args 0 4] return SQLITE_OK } do_test auth-6.2 { diff --git a/test/auth2.test b/test/auth2.test index 65e0591249..a9d64d08af 100644 --- a/test/auth2.test +++ b/test/auth2.test @@ -31,7 +31,7 @@ do_test auth2-1.1 { INSERT INTO t1 VALUES(1,2,3); } set ::flist {} - proc auth {code arg1 arg2 arg3 arg4} { + proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_FUNCTION"} { lappend ::flist $arg2 if {$arg2=="max"} { @@ -80,7 +80,7 @@ sqlite3 db test.db sqlite3 db2 test.db proc auth {args} { global authargs - append authargs $args\n + append authargs [lrange $args 0 4]\n return SQLITE_OK } db auth auth diff --git a/test/auth3.test b/test/auth3.test index 21e2b3b65d..eef10b398f 100644 --- a/test/auth3.test +++ b/test/auth3.test @@ -30,7 +30,7 @@ if {[catch {db auth {}} msg]} { db cache size 0 db authorizer ::auth -proc auth {code arg1 arg2 arg3 arg4} { +proc auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_DELETE"} { return $::authcode } diff --git a/test/fkey2.test b/test/fkey2.test index 4c8daa0b02..53b90dc91c 100644 --- a/test/fkey2.test +++ b/test/fkey2.test @@ -1554,7 +1554,7 @@ ifcapable auth { } } {} - proc auth {args} {eval lappend ::authargs $args ; return SQLITE_OK} + proc auth {args} {eval lappend ::authargs [lrange $args 0 4]; return SQLITE_OK} db auth auth # An insert on the parent table must read the child key of any deferred diff --git a/test/fts4aa.test b/test/fts4aa.test index 88550c99f7..e6c7f9336e 100644 --- a/test/fts4aa.test +++ b/test/fts4aa.test @@ -170,7 +170,7 @@ foreach {q r} [array get fts4aa_res] { # Should get the same search results when an authorizer prevents # all PRAGMA statements. # -proc no_pragma_auth {code arg1 arg2 arg3 arg4} { +proc no_pragma_auth {code arg1 arg2 arg3 arg4 args} { if {$code=="SQLITE_PRAGMA"} {return SQLITE_DENY} return SQLITE_OK; } diff --git a/test/savepoint.test b/test/savepoint.test index 9f4571abef..9362c8fe19 100644 --- a/test/savepoint.test +++ b/test/savepoint.test @@ -561,7 +561,7 @@ do_test savepoint-8-2 { # ifcapable auth { proc auth {args} { - eval lappend ::authdata $args + eval lappend ::authdata [lrange $args 0 4] return SQLITE_OK } db auth auth @@ -583,7 +583,7 @@ ifcapable auth { } {SQLITE_SAVEPOINT RELEASE sp1 {} {}} proc auth {args} { - eval lappend ::authdata $args + eval lappend ::authdata [lrange $args 0 4] return SQLITE_DENY } db auth auth diff --git a/test/vtab3.test b/test/vtab3.test index ebf8369d5d..e8c6982a57 100644 --- a/test/vtab3.test +++ b/test/vtab3.test @@ -25,7 +25,7 @@ set ::auth_fail 0 set ::auth_log [list] set ::auth_filter [list SQLITE_READ SQLITE_UPDATE SQLITE_SELECT SQLITE_PRAGMA] -proc auth {code arg1 arg2 arg3 arg4} { +proc auth {code arg1 arg2 arg3 arg4 args} { if {[lsearch $::auth_filter $code]>-1} { return SQLITE_OK } diff --git a/test/without_rowid3.test b/test/without_rowid3.test index c4c2d6f483..a0dc76d3f9 100644 --- a/test/without_rowid3.test +++ b/test/without_rowid3.test @@ -1621,7 +1621,7 @@ ifcapable auth { } } {} - proc auth {args} {eval lappend ::authargs $args ; return SQLITE_OK} + proc auth {args} {eval lappend ::authargs [lrange $args 0 4]; return SQLITE_OK} db auth auth # An insert on the parent table must read the child key of any deferred From b2445d5ee8b58a4e9e006d697e14dae3f4c43cad Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 14:01:41 +0000 Subject: [PATCH 17/30] Move user authentication blocking from sqlite3_prepare() over to the table lock generator, thus allowing SQL statements (like "PRAGMA locking_mode") that do not touch database content to run prior to authentication. FossilOrigin-Name: 70121e7cf868b7d6d19bf98794ddc3809a901456 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 18 ++++++++++++++++++ src/pragma.c | 2 +- src/prepare.c | 14 -------------- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 12328063d0..2e3e9eb42d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sthe\sextra\sparameter\son\sthe\ssqlite3_set_authorizer()\scallback\nand\ssupport\sfor\sfailing\san\sATTACH\swith\san\sauthentication-required\sdatabase\nusing\sbad\scredentials.\s\sThe\sextension\sis\snow\sfeature\scomplete,\sbut\smuch\ntesting\sand\sbug-fixing\sremains. -D 2014-09-11T13:44:52.150 +C Move\suser\sauthentication\sblocking\sfrom\ssqlite3_prepare()\sover\sto\sthe\ntable\slock\sgenerator,\sthus\sallowing\sSQL\sstatements\s(like\s\n"PRAGMA\slocking_mode")\sthat\sdo\snot\stouch\sdatabase\scontent\sto\srun\nprior\sto\sauthentication. +D 2014-09-11T14:01:41.319 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc -F src/build.c 4c7aac1ddda782c6f1cad84aeabec6e8d0be7495 +F src/build.c 8b02494e4dc9c4a6c9aff1cac8b40c426733f025 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/ctime.c 16cd19215d9fd849ee2b7509b092f2e0bbd6a958 @@ -220,8 +220,8 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa -F src/pragma.c 3b7b1a5e90804006f44c65464c7032ee6a1d24e3 -F src/prepare.c f82c009a763e739c6bdf02a270ccfda9e54f783c +F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f +F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196 F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2f6d8f32eef526b5912f42ab467e3c7812480d8b -R 8b68610f4a9d73b92fb9d68a3359baf2 +P 596e728b0eb19a34c888e33d4d37978ca2bf1e00 +R c54f70fc39612d9ea503f6c456a7ab1f U drh -Z 6a1c7f3384e27f9ad12e8ea277382ab2 +Z e2993baf94376fc5d680228ffe933715 diff --git a/manifest.uuid b/manifest.uuid index 1b3da62f36..a5702df9c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -596e728b0eb19a34c888e33d4d37978ca2bf1e00 \ No newline at end of file +70121e7cf868b7d6d19bf98794ddc3809a901456 \ No newline at end of file diff --git a/src/build.c b/src/build.c index c94c5a1310..d95cf849e6 100644 --- a/src/build.c +++ b/src/build.c @@ -156,6 +156,24 @@ void sqlite3FinishCoding(Parse *pParse){ while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){} sqlite3VdbeAddOp0(v, OP_Halt); +#if SQLITE_USER_AUTHENTICATION + if( pParse->nTableLock>0 && db->init.busy==0 ){ + if( db->auth.authLevelauth.authLevel==UAUTH_Unknown ){ + u8 authLevel = UAUTH_Fail; + sqlite3UserAuthCheckLogin(db, "main", &authLevel); + db->auth.authLevel = authLevel; + if( authLevelflags &= ~SQLITE_WriteSchema; + } + if( db->auth.authLevelrc = SQLITE_AUTH_USER; + sqlite3ErrorMsg(pParse, "user not authenticated"); + return; + } + } + } +#endif + /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a diff --git a/src/pragma.c b/src/pragma.c index cbd593f215..543f265ba9 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1398,7 +1398,7 @@ void sqlite3Pragma( mask &= ~(SQLITE_ForeignKeys); } #if SQLITE_USER_AUTHENTICATION - if( db->auth.authLevelauth.authLevel==UAUTH_User ){ /* Do not allow non-admin users to modify the schema arbitrarily */ mask &= ~(SQLITE_WriteSchema); } diff --git a/src/prepare.c b/src/prepare.c index c57fda0026..a05e619f3e 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -715,20 +715,6 @@ static int sqlite3LockAndPrepare( return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db->mutex); -#if SQLITE_USER_AUTHENTICATION - if( db->auth.authLevelauth.authLevel==UAUTH_Unknown ){ - u8 authLevel = UAUTH_Fail; - sqlite3UserAuthCheckLogin(db, "main", &authLevel); - db->auth.authLevel = authLevel; - } - if( db->auth.authLevelmutex); - return SQLITE_ERROR; - } - } -#endif sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail); if( rc==SQLITE_SCHEMA ){ From 570f187f78872b349cea66822595cc23304dc378 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 14:40:27 +0000 Subject: [PATCH 18/30] Fix the sqlite3_user_change() interface so that it does allow a non-admin user to change their own password. FossilOrigin-Name: 52d440c7e1b07fc03f14ed5fa4cc4c89a75cd430 --- ext/userauth/user-auth.txt | 23 ++++++++++----------- ext/userauth/userauth.c | 30 ++++++++++++++++++--------- manifest | 16 +++++++-------- manifest.uuid | 2 +- test/userauth01.test | 42 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 31 deletions(-) diff --git a/ext/userauth/user-auth.txt b/ext/userauth/user-auth.txt index 8b64617c36..ba4eabc137 100644 --- a/ext/userauth/user-auth.txt +++ b/ext/userauth/user-auth.txt @@ -44,12 +44,11 @@ By default a database does not require authentication. The sqlite3_open(), sqlite3_open16(), and sqlite3_open_v2() interfaces work as before: they open a new database connection. However, if the -database being opened requires authentication, then attempts to prepare -SQL statements (using sqlite3_prepare_v2(), for example) will fail -with an SQLITE_AUTH error until after sqlite3_user_authenticate() -has been called successfully. The sqlite3_user_authenticate() call -will return SQLITE_OK if the authentication credentials are accepted -and SQLITE_ERROR if not. +database being opened requires authentication, then attempts to read +or write from the database will fail with an SQLITE_AUTH error until +after sqlite3_user_authenticate() has been called successfully. The +sqlite3_user_authenticate() call will return SQLITE_OK if the +authentication credentials are accepted and SQLITE_ERROR if not. Calling sqlite3_user_authenticate() on a no-authentication-required database connection is a harmless no-op. @@ -133,12 +132,12 @@ new table: pw BLOB ) WITHOUT ROWID; -This table is inaccessible (unreadable and unwriteable) to non-admin users -and is read-only for admin users. However, if the same database file is -opened by a version of SQLite that omits the -DSQLITE_USER_AUTHENTICATION -compile-time option, then the sqlite_user table will be readable by -anybody and writeable by anybody if the "PRAGMA writable_schema=ON" -statement is run first. +The sqlite_user table is inaccessible (unreadable and unwriteable) to +non-admin users and is read-only for admin users. However, if the same +database file is opened by a version of SQLite that omits +the -DSQLITE_USER_AUTHENTICATION compile-time option, then the sqlite_user +table will be readable by anybody and writeable by anybody if +the "PRAGMA writable_schema=ON" statement is run first. The sqlite_user.pw field is encoded by a built-in SQL function "sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 343e49e6ff..19e9f6f762 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -268,7 +268,11 @@ int sqlite3_user_change( int isAdmin /* Modified admin privilege for the user */ ){ sqlite3_stmt *pStmt; - if( db->auth.authLevelauth.authLevel; + if( authLevelauth.authLevel==UAUTH_Admin) ){ + }else if( isAdmin!=(authLevel==UAUTH_Admin) ){ /* Cannot change the isAdmin setting for self */ return SQLITE_AUTH; } + db->auth.authLevel = UAUTH_Admin; if( !userTableExists(db, "main") ){ /* This routine is a no-op if the user to be modified does not exist */ - return SQLITE_OK; + }else{ + pStmt = sqlite3UserAuthPrepare(db, + "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)" + " WHERE uname=%Q", isAdmin, zUsername); + if( pStmt==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_finalize(pStmt); + } } - pStmt = sqlite3UserAuthPrepare(db, - "UPDATE sqlite_user SET isAdmin=%d, pw=sqlite_crypt(?1,NULL)" - " WHERE uname=%Q", isAdmin, zUsername); - if( pStmt==0 ) return SQLITE_NOMEM; - sqlite3_bind_blob(pStmt, 1, aPW, nPW, SQLITE_STATIC); - sqlite3_step(pStmt); - return sqlite3_finalize(pStmt); + db->auth.authLevel = authLevel; + return rc; } /* diff --git a/manifest b/manifest index 2e3e9eb42d..b1a2451fb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\suser\sauthentication\sblocking\sfrom\ssqlite3_prepare()\sover\sto\sthe\ntable\slock\sgenerator,\sthus\sallowing\sSQL\sstatements\s(like\s\n"PRAGMA\slocking_mode")\sthat\sdo\snot\stouch\sdatabase\scontent\sto\srun\nprior\sto\sauthentication. -D 2014-09-11T14:01:41.319 +C Fix\sthe\ssqlite3_user_change()\sinterface\sso\sthat\sit\sdoes\sallow\sa\nnon-admin\suser\sto\schange\stheir\sown\spassword. +D 2014-09-11T14:40:27.156 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -145,8 +145,8 @@ F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 -F ext/userauth/user-auth.txt 527aaec593ae34dcaf543324623c8351a5d33d3f -F ext/userauth/userauth.c a66cd3abcc3b2c10b3999ab49f900d561e8ddd33 +F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 +F ext/userauth/userauth.c bcd1aedb0b810b1a1125945e637af54ce3d299f1 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -1057,7 +1057,7 @@ F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b -F test/userauth01.test 695ead5a47e8827dea283abca69c121b679176af +F test/userauth01.test 3be4d454af151aa8d59804f2fe4e593f367014c3 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324 @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 596e728b0eb19a34c888e33d4d37978ca2bf1e00 -R c54f70fc39612d9ea503f6c456a7ab1f +P 70121e7cf868b7d6d19bf98794ddc3809a901456 +R fc5d3c327123005770c7e41594123732 U drh -Z e2993baf94376fc5d680228ffe933715 +Z 21dad64c9f9cfa4863908b784242b9b1 diff --git a/manifest.uuid b/manifest.uuid index a5702df9c7..5b03dbec59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70121e7cf868b7d6d19bf98794ddc3809a901456 \ No newline at end of file +52d440c7e1b07fc03f14ed5fa4cc4c89a75cd430 \ No newline at end of file diff --git a/test/userauth01.test b/test/userauth01.test index 60e617e3ba..9f0eb5d85a 100644 --- a/test/userauth01.test +++ b/test/userauth01.test @@ -70,5 +70,47 @@ do_test userauth01-1.5 { } } {NULL 1 2.5 'three' X'4444' alice 1 sqlite_user t1} +# The sqlite3_user_add() interface can be used (by an admin user only) +# to create a new user. +# +do_test userauth01-1.6 { + sqlite3_user_add db bob pw-4-bob 0 + sqlite3_user_add db cindy pw-4-cindy 0 + sqlite3_user_add db david pw-4-david 0 + execsql { + SELECT uname, isadmin FROM sqlite_user ORDER BY uname; + } +} {alice 1 bob 0 cindy 0 david 0} + +# The sqlite_user table is inaccessible (unreadable and unwriteable) to +# non-admin users and is read-only for admin users. However, if the same +# +do_test userauth01-1.7 { + sqlite3 db2 test.db + sqlite3_user_authenticate db2 cindy pw-4-cindy + db2 eval { + SELECT quote(x) FROM t1 ORDER BY x; + SELECT name FROM sqlite_master ORDER BY name; + } +} {NULL 1 2.5 'three' X'4444' sqlite_user t1} +do_test userauth01-1.8 { + catchsql { + SELECT uname, isadmin FROM sqlite_user ORDER BY uname; + } db2 +} {1 {no such table: sqlite_user}} + +# Any user can change their own password. +# +do_test userauth01-1.9 { + sqlite3_user_change db2 cindy xyzzy-cindy 0 +} {SQLITE_OK} +do_test userauth01-1.10 { + sqlite3_user_authenticate db2 cindy pw-4-cindy +} {SQLITE_AUTH} +do_test userauth01-1.11 { + sqlite3_user_authenticate db2 cindy xyzzy-cindy +} {SQLITE_OK} + + finish_test From 9d5b0df132ad3abec0bc0aa2913814e845909b05 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 14:56:45 +0000 Subject: [PATCH 19/30] Get the sqlite3_user_delete() interface working. FossilOrigin-Name: 974a9c65583f7ab438d5673dc00c347ab8322855 --- ext/userauth/userauth.c | 2 +- manifest | 14 +++---- manifest.uuid | 2 +- test/userauth01.test | 89 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 9 deletions(-) diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 19e9f6f762..21d33ce80f 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -329,7 +329,7 @@ int sqlite3_user_delete( return SQLITE_OK; } pStmt = sqlite3UserAuthPrepare(db, - "SELECT FROM sqlite_user WHERE uname=%Q", zUsername); + "DELETE FROM sqlite_user WHERE uname=%Q", zUsername); if( pStmt==0 ) return SQLITE_NOMEM; sqlite3_step(pStmt); return sqlite3_finalize(pStmt); diff --git a/manifest b/manifest index b1a2451fb1..f5797939b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3_user_change()\sinterface\sso\sthat\sit\sdoes\sallow\sa\nnon-admin\suser\sto\schange\stheir\sown\spassword. -D 2014-09-11T14:40:27.156 +C Get\sthe\ssqlite3_user_delete()\sinterface\sworking. +D 2014-09-11T14:56:45.837 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -146,7 +146,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 -F ext/userauth/userauth.c bcd1aedb0b810b1a1125945e637af54ce3d299f1 +F ext/userauth/userauth.c 7942172fe537a6eedb797535b7558e726e00f728 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -1057,7 +1057,7 @@ F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b -F test/userauth01.test 3be4d454af151aa8d59804f2fe4e593f367014c3 +F test/userauth01.test 77f6762fd30e09a70c08ae1734fc63cc1e2f214a F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324 @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 70121e7cf868b7d6d19bf98794ddc3809a901456 -R fc5d3c327123005770c7e41594123732 +P 52d440c7e1b07fc03f14ed5fa4cc4c89a75cd430 +R f24750ae4706249df9137bdaab459848 U drh -Z 21dad64c9f9cfa4863908b784242b9b1 +Z 7444bd078e3d35d0ed86c3e87803a00a diff --git a/manifest.uuid b/manifest.uuid index 5b03dbec59..d912814cf2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52d440c7e1b07fc03f14ed5fa4cc4c89a75cd430 \ No newline at end of file +974a9c65583f7ab438d5673dc00c347ab8322855 \ No newline at end of file diff --git a/test/userauth01.test b/test/userauth01.test index 9f0eb5d85a..a914ea07ca 100644 --- a/test/userauth01.test +++ b/test/userauth01.test @@ -110,7 +110,96 @@ do_test userauth01-1.10 { do_test userauth01-1.11 { sqlite3_user_authenticate db2 cindy xyzzy-cindy } {SQLITE_OK} +do_test userauth01-1.12 { + sqlite3_user_change db alice xyzzy-alice 1 +} {SQLITE_OK} +do_test userauth01-1.13 { + sqlite3_user_authenticate db alice pw-4-alice +} {SQLITE_AUTH} +do_test userauth01-1.14 { + sqlite3_user_authenticate db alice xyzzy-alice +} {SQLITE_OK} +# No user may change their own admin privilege setting. +# +do_test userauth01-1.15 { + sqlite3_user_change db alice xyzzy-alice 0 +} {SQLITE_AUTH} +do_test userauth01-1.16 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 bob 0 cindy 0 david 0} +do_test userauth01-1.17 { + sqlite3_user_change db2 cindy xyzzy-cindy 1 +} {SQLITE_AUTH} +do_test userauth01-1.18 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 bob 0 cindy 0 david 0} + +# The sqlite3_user_change() interface can be used to change a users +# login credentials or admin privilege. +# +do_test userauth01-1.20 { + sqlite3_user_change db david xyzzy-david 1 +} {SQLITE_OK} +do_test userauth01-1.21 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 bob 0 cindy 0 david 1} +do_test userauth01-1.22 { + sqlite3_user_authenticate db2 david xyzzy-david +} {SQLITE_OK} +do_test userauth01-1.23 { + db2 eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 bob 0 cindy 0 david 1} +do_test userauth01-1.24 { + sqlite3_user_change db david pw-4-david 0 +} {SQLITE_OK} +do_test userauth01-1.25 { + sqlite3_user_authenticate db2 david pw-4-david +} {SQLITE_OK} +do_test userauth01-1.26 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 bob 0 cindy 0 david 0} +do_test userauth01-1.27 { + catchsql {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} db2 +} {1 {no such table: sqlite_user}} + +# Only an admin user can change another users login +# credentials or admin privilege setting. +# +do_test userauth01-1.30 { + sqlite3_user_change db2 bob xyzzy-bob 1 +} {SQLITE_AUTH} +do_test userauth01-1.31 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 bob 0 cindy 0 david 0} + +# The sqlite3_user_delete() interface can be used (by an admin user only) +# to delete a user. +# +do_test userauth01-1.40 { + sqlite3_user_delete db bob +} {SQLITE_OK} +do_test userauth01-1.41 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 cindy 0 david 0} +do_test userauth01-1.42 { + sqlite3_user_delete db2 cindy +} {SQLITE_AUTH} +do_test userauth01-1.43 { + sqlite3_user_delete db2 alice +} {SQLITE_AUTH} +do_test userauth01-1.44 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 cindy 0 david 0} + +# The currently logged-in user cannot be deleted +# +do_test userauth01-1.50 { + sqlite3_user_delete db alice +} {SQLITE_AUTH} +do_test userauth01-1.51 { + db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} +} {alice 1 cindy 0 david 0} finish_test From a000ca681aa71c7efb4b9ab91f8ae6ca2bf289d3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 15:25:02 +0000 Subject: [PATCH 20/30] All interfaces working and tested. FossilOrigin-Name: 96ea5c0b3cd1dec81d490f2f958ebd2e47a24921 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/attach.c | 2 +- test/userauth01.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f5797939b4..f6d0875475 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Get\sthe\ssqlite3_user_delete()\sinterface\sworking. -D 2014-09-11T14:56:45.837 +C All\sinterfaces\sworking\sand\stested. +D 2014-09-11T15:25:02.114 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb F src/analyze.c 79383a54fee3b7f1fb03dd4c8c8115583f506de5 -F src/attach.c cc9b30041dfcd24be0a47986c87c384515c54449 +F src/attach.c f4e94df2d1826feda65eb0939f7f6f5f923a0ad9 F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb @@ -1057,7 +1057,7 @@ F test/unixexcl.test cd6c765f75e50e8e2c2ba763149e5d340ea19825 F test/unordered.test ca7adce0419e4ca0c50f039885e76ed2c531eda8 F test/update.test 1b6c488a8f993d090b7ee9ad0e234faa161b3aeb F test/uri.test 23662b7b61958b0f0e47082de7d06341ccf85d5b -F test/userauth01.test 77f6762fd30e09a70c08ae1734fc63cc1e2f214a +F test/userauth01.test de260ba56ca288e36f10fc86cdd6e30be0c96edb F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324 @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 52d440c7e1b07fc03f14ed5fa4cc4c89a75cd430 -R f24750ae4706249df9137bdaab459848 +P 974a9c65583f7ab438d5673dc00c347ab8322855 +R 1b82e61677dc0f31739c2e6eefc2d964 U drh -Z 7444bd078e3d35d0ed86c3e87803a00a +Z fb0835cb3153cdbefaf30b784736228d diff --git a/manifest.uuid b/manifest.uuid index d912814cf2..adf124ebaf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -974a9c65583f7ab438d5673dc00c347ab8322855 \ No newline at end of file +96ea5c0b3cd1dec81d490f2f958ebd2e47a24921 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 5763e631ad..cf52bb24b1 100644 --- a/src/attach.c +++ b/src/attach.c @@ -212,7 +212,7 @@ static void attachFunc( u8 newAuth = 0; rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); if( newAuthauth.authLevel ){ - rc = SQLITE_AUTH; + rc = SQLITE_AUTH_USER; } } #endif diff --git a/test/userauth01.test b/test/userauth01.test index a914ea07ca..a4621dc72f 100644 --- a/test/userauth01.test +++ b/test/userauth01.test @@ -201,5 +201,41 @@ do_test userauth01-1.51 { db eval {SELECT uname, isadmin FROM sqlite_user ORDER BY uname} } {alice 1 cindy 0 david 0} +# When ATTACH-ing new database files to a connection, each newly attached +# database that is an authentication-required database is checked using +# the same username and password as supplied to the main database. If that +# check fails, then the ATTACH command fails with an SQLITE_AUTH error. +# +do_test userauth01-1.60 { + forcedelete test3.db + sqlite3 db3 test3.db + db3 eval { + CREATE TABLE t3(a,b,c); INSERT INTO t3 VALUES(1,2,3); + SELECT * FROM t3; + } +} {1 2 3} +do_test userauth01-1.61 { + sqlite3_user_add db3 alice xyzzy-alice 1 +} {SQLITE_OK} +do_test userauth01-1.62 { + db eval { + ATTACH 'test3.db' AS aux; + SELECT * FROM t1, t3 ORDER BY x LIMIT 1; + DETACH aux; + } +} {{} 1 2 3} +do_test userauth01-1.63 { + sqlite3_user_change db alice pw-4-alice 1 + sqlite3_user_authenticate db alice pw-4-alice + catchsql { + ATTACH 'test3.db' AS aux; + } +} {1 {unable to open database: test3.db}} +do_test userauth01-1.64 { + sqlite3_extended_errcode db +} {SQLITE_AUTH} +do_test userauth01-1.65 { + db eval {PRAGMA database_list} +} {~/test3.db/} finish_test From 7883ecfcd40c8bcf60cb69a36459f6f4f6242824 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 16:19:31 +0000 Subject: [PATCH 21/30] Enhance the sqlite3_user_add() interface to initialize the user authentication logic. Add test cases for the extra argument on the end of the authorizer callback. FossilOrigin-Name: 842c6da8f1a62bd13a1b4089a98b0835a46a2285 --- ext/userauth/userauth.c | 16 ++++++++++++++++ manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 15 ++++----------- src/shell.c | 1 + src/sqliteInt.h | 1 + test/userauth01.test | 22 +++++++++++++++++++--- 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index 21d33ce80f..d368df8f9d 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -118,6 +118,8 @@ int sqlite3UserAuthCheckLogin( ){ int rc; u8 savedAuthLevel; + assert( zDb!=0 ); + assert( peAuth!=0 ); savedAuthLevel = db->auth.authLevel; db->auth.authLevel = UAUTH_Admin; rc = userAuthCheckLogin(db, zDb, peAuth); @@ -125,6 +127,19 @@ int sqlite3UserAuthCheckLogin( return rc; } +/* +** If the current authLevel is UAUTH_Unknown, the take actions to figure +** out what authLevel should be +*/ +void sqlite3UserAuthInit(sqlite3 *db){ + if( db->auth.authLevel==UAUTH_Unknown ){ + u8 authLevel = UAUTH_Fail; + sqlite3UserAuthCheckLogin(db, "main", &authLevel); + db->auth.authLevel = authLevel; + if( authLevelflags &= ~SQLITE_WriteSchema; + } +} + /* ** Implementation of the sqlite_crypt(X,Y) function. ** @@ -223,6 +238,7 @@ int sqlite3_user_add( ){ sqlite3_stmt *pStmt; int rc; + sqlite3UserAuthInit(db); if( db->auth.authLevelnTableLock>0 && db->init.busy==0 ){ + sqlite3UserAuthInit(db); if( db->auth.authLevelauth.authLevel==UAUTH_Unknown ){ - u8 authLevel = UAUTH_Fail; - sqlite3UserAuthCheckLogin(db, "main", &authLevel); - db->auth.authLevel = authLevel; - if( authLevelflags &= ~SQLITE_WriteSchema; - } - if( db->auth.authLevelrc = SQLITE_AUTH_USER; - sqlite3ErrorMsg(pParse, "user not authenticated"); - return; - } + pParse->rc = SQLITE_AUTH_USER; + sqlite3ErrorMsg(pParse, "user not authenticated"); + return; } } #endif diff --git a/src/shell.c b/src/shell.c index b8ab2dbe9f..ec83b13910 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3445,6 +3445,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } + open_db(p, 0); if( strcmp(azArg[1],"login")==0 ){ if( nArg!=4 ){ fprintf(stderr, "Usage: .user login USER PASSWORD\n"); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a9f2001457..805c925f79 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1010,6 +1010,7 @@ struct sqlite3_userauth { /* Functions used only by user authorization logic */ int sqlite3UserAuthTable(const char*); int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); +void sqlite3UserAuthInit(sqlite3*); void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); #endif /* SQLITE_USER_AUTHENTICATION */ diff --git a/test/userauth01.test b/test/userauth01.test index a4621dc72f..644937b192 100644 --- a/test/userauth01.test +++ b/test/userauth01.test @@ -209,14 +209,14 @@ do_test userauth01-1.51 { do_test userauth01-1.60 { forcedelete test3.db sqlite3 db3 test3.db + sqlite3_user_add db3 alice xyzzy-alice 1 +} {SQLITE_OK} +do_test userauth01-1.61 { db3 eval { CREATE TABLE t3(a,b,c); INSERT INTO t3 VALUES(1,2,3); SELECT * FROM t3; } } {1 2 3} -do_test userauth01-1.61 { - sqlite3_user_add db3 alice xyzzy-alice 1 -} {SQLITE_OK} do_test userauth01-1.62 { db eval { ATTACH 'test3.db' AS aux; @@ -238,4 +238,20 @@ do_test userauth01-1.65 { db eval {PRAGMA database_list} } {~/test3.db/} +# The sqlite3_set_authorizer() callback is modified to take a 7th parameter +# which is the username of the currently logged in user, or NULL for a +# no-authentication-required database. +# +proc auth {args} { + lappend ::authargs $args + return SQLITE_OK +} +do_test authuser01-2.1 { + unset -nocomplain ::authargs + db auth auth + db eval {SELECT x FROM t1} + set ::authargs +} {/SQLITE_SELECT {} {} {} {} alice/} + + finish_test From 3a3a03f29e0072dd0ded8d644307f5b1a31633f5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 16:36:43 +0000 Subject: [PATCH 22/30] Suppress the potential schema error that occurs when a non-user-auth SQLite library tries to parse the sqlite_user table definition in a user-auth database. FossilOrigin-Name: cda33c1ef35416a155af602c0b4e9d42ccf8633f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index bbf33a5fb6..3fc0ea1b3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3_user_add()\sinterface\sto\sinitialize\sthe\suser\nauthentication\slogic.\s\sAdd\stest\scases\sfor\sthe\sextra\sargument\son\sthe\nend\sof\sthe\sauthorizer\scallback. -D 2014-09-11T16:19:31.719 +C Suppress\sthe\spotential\sschema\serror\sthat\soccurs\swhen\sa\snon-user-auth\nSQLite\slibrary\stries\sto\sparse\sthe\ssqlite_user\stable\sdefinition\sin\sa\nuser-auth\sdatabase. +D 2014-09-11T16:36:43.549 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 F src/btree.c b1c1cd1cc3ae2e433a23b9a6c9ab53805707d8cd F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc -F src/build.c 555826ae03c3bc589a7b09b279c2e5ba989a4178 +F src/build.c 047d7e1d2d89fa55134fa1d6b669c9c2983c0d11 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/ctime.c 16cd19215d9fd849ee2b7509b092f2e0bbd6a958 @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 96ea5c0b3cd1dec81d490f2f958ebd2e47a24921 -R 279311d0c4a57cb81a913da29cc5dd35 +P 842c6da8f1a62bd13a1b4089a98b0835a46a2285 +R 7de809a255ed1cf8a77cea399ddd7268 U drh -Z cf3239448d4f92059057a29736710c2c +Z 0b3d163c7ef70d6122b5132c30860c28 diff --git a/manifest.uuid b/manifest.uuid index 78c06de5d3..8aae504135 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -842c6da8f1a62bd13a1b4089a98b0835a46a2285 \ No newline at end of file +cda33c1ef35416a155af602c0b4e9d42ccf8633f \ No newline at end of file diff --git a/src/build.c b/src/build.c index 84ffb0a38c..791f6f2033 100644 --- a/src/build.c +++ b/src/build.c @@ -2901,6 +2901,7 @@ Index *sqlite3CreateIndex( assert( pTab!=0 ); assert( pParse->nErr==0 ); if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && db->init.busy==0 #if SQLITE_USER_AUTHENTICATION && sqlite3UserAuthTable(pTab->zName)==0 #endif From c891c6c7adf9be3296fba6fef24012893a9bb8c2 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 17:14:54 +0000 Subject: [PATCH 23/30] Clean up some #includes in the extension API implementation. FossilOrigin-Name: b149ef5c639e6bcff7bd1c7866353e7f7f468070 --- ext/userauth/userauth.c | 5 +++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ext/userauth/userauth.c b/ext/userauth/userauth.c index d368df8f9d..6ce99053d3 100644 --- a/ext/userauth/userauth.c +++ b/ext/userauth/userauth.c @@ -22,8 +22,9 @@ ** directory as this file for additional information. */ #ifdef SQLITE_USER_AUTHENTICATION -#include "sqliteInt.h" -#include "sqlite3userauth.h" +#ifndef _SQLITEINT_H_ +# include "sqliteInt.h" +#endif /* ** Prepare an SQL statement for use by the user authentication logic. diff --git a/manifest b/manifest index 3fc0ea1b3f..10ecd71450 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Suppress\sthe\spotential\sschema\serror\sthat\soccurs\swhen\sa\snon-user-auth\nSQLite\slibrary\stries\sto\sparse\sthe\ssqlite_user\stable\sdefinition\sin\sa\nuser-auth\sdatabase. -D 2014-09-11T16:36:43.549 +C Clean\sup\ssome\s#includes\sin\sthe\sextension\sAPI\simplementation. +D 2014-09-11T17:14:54.772 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -146,7 +146,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/userauth/sqlite3userauth.h 19cb6f0e31316d0ee4afdfb7a85ef9da3333a220 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 -F ext/userauth/userauth.c 02a52c3c345a8dede3a1018c08840b74230acc51 +F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 842c6da8f1a62bd13a1b4089a98b0835a46a2285 -R 7de809a255ed1cf8a77cea399ddd7268 +P cda33c1ef35416a155af602c0b4e9d42ccf8633f +R 6795c3f7d8a461e29887bf50932299a0 U drh -Z 0b3d163c7ef70d6122b5132c30860c28 +Z 25539858b9c10651bb38a3461b6abb42 diff --git a/manifest.uuid b/manifest.uuid index 8aae504135..9d753fddf9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cda33c1ef35416a155af602c0b4e9d42ccf8633f \ No newline at end of file +b149ef5c639e6bcff7bd1c7866353e7f7f468070 \ No newline at end of file From fc59a954cbce32be71da37d7ca1f447396ba39e0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 11 Sep 2014 23:34:55 +0000 Subject: [PATCH 24/30] Fix an issue with sqlite3_bind_text64() with the SQLITE_UTF16 encoding parameter. Remove some unreachable code from the text64() and blob64() implementation. FossilOrigin-Name: 34292b084ef48cd6e9ca5704f6b072a29733b4c2 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbeapi.c | 8 ++++++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 24f2ea483a..c83ebe16ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sAPIs\sthat\stake\s64-bit\slength\sparameters:\ssqlite3_malloc64(),\nsqlite3_realloc64(),\ssqlite3_bind_blob64(),\ssqlite3_bind_text64(),\nsqlite3_result_blob64(),\sand\ssqlite3_result_text64().\nAdd\sthe\ssqlite3_msize()\sinterface.\nInternal\smemory\sallocation\sroutines\snow\suse\s64-bit\sunsigned\nlength\sparameters\sfor\ssafety.\nFix\sthe\ssqlite3_get_table()\sto\suse\ssqlite3_realloc64()\sto\savoid\na\sinteger\soverflow\sproblem. -D 2014-09-11T18:44:04.913 +C Fix\san\sissue\swith\ssqlite3_bind_text64()\swith\sthe\sSQLITE_UTF16\sencoding\nparameter.\s\sRemove\ssome\sunreachable\scode\sfrom\sthe\stext64()\sand\sblob64()\nimplementation. +D 2014-09-11T23:34:55.607 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,7 +291,7 @@ F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h b4843c35c3ba533b69d4250f550b5bacf2fb013d -F src/vdbeapi.c cec65a12dc2fe9072d5108d9f75df57b0324883a +F src/vdbeapi.c 06b712d4772b318b69cd37a416deb1ff0426aa8c F src/vdbeaux.c 91fd1e0c54a765838dc61fcf79f31acce035ce38 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a @@ -1197,8 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 65884d4f81a4705b0356b6cb8ec4909945ff5c19 6ab76c5fedfe568b0f0f34a600f9135bf6558148 -R a34346a4fba04f6707f06567bf21377a -T +closed 6ab76c5fedfe568b0f0f34a600f9135bf6558148 +P 7e4978c003867d1b532b69221013dda75ca61953 +R 5b504a805873df7c692d762cd653895b U drh -Z ecfd648f0ae419a16a536c86444de6f4 +Z 9235587180e257c32aca7830c18cbf2e diff --git a/manifest.uuid b/manifest.uuid index 0feb233a2e..1b709cc082 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e4978c003867d1b532b69221013dda75ca61953 \ No newline at end of file +34292b084ef48cd6e9ca5704f6b072a29733b4c2 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 4dccb30c15..b64f33c8c6 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -235,12 +235,11 @@ static int invokeValueDestructor( void (*xDel)(void*), /* The destructor */ sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ ){ + assert( xDel!=SQLITE_DYNAMIC ); if( xDel==0 ){ /* noop */ }else if( xDel==SQLITE_TRANSIENT ){ /* noop */ - }else if( xDel==SQLITE_DYNAMIC ){ - sqlite3_free((void*)p); }else{ xDel((void*)p); } @@ -264,6 +263,7 @@ void sqlite3_result_blob64( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ @@ -317,6 +317,7 @@ void sqlite3_result_text64( unsigned char enc ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( xDel!=SQLITE_DYNAMIC ); if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ @@ -1179,6 +1180,7 @@ int sqlite3_bind_blob64( sqlite3_uint64 nData, void (*xDel)(void*) ){ + assert( xDel!=SQLITE_DYNAMIC ); if( nData>0x7fffffff ){ return invokeValueDestructor(zData, xDel, 0); }else{ @@ -1234,9 +1236,11 @@ int sqlite3_bind_text64( void (*xDel)(void*), unsigned char enc ){ + assert( xDel!=SQLITE_DYNAMIC ); if( nData>0x7fffffff ){ return invokeValueDestructor(zData, xDel, 0); }else{ + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; return bindText(pStmt, i, zData, nData, xDel, enc); } } From fb046e7653a1dee6e34b8b3b2ab71ebf0582de2c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Sep 2014 04:28:33 +0000 Subject: [PATCH 25/30] Fix a problem with parser memory allocation on 32-bit systems. FossilOrigin-Name: 2f69a1fa6adc9377149ae7faa586a5d30b6a631b --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/lempar.c | 4 ++-- src/sqliteInt.h | 2 +- src/tokenize.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c83ebe16ff..4c19df8ec5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\swith\ssqlite3_bind_text64()\swith\sthe\sSQLITE_UTF16\sencoding\nparameter.\s\sRemove\ssome\sunreachable\scode\sfrom\sthe\stext64()\sand\sblob64()\nimplementation. -D 2014-09-11T23:34:55.607 +C Fix\sa\sproblem\swith\sparser\smemory\sallocation\son\s32-bit\ssystems. +D 2014-09-12T04:28:33.110 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -191,7 +191,7 @@ F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/insert.c 0b073fade178d9dbd990bbb32b4438e50b884a06 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e -F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b +F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994 F src/main.c d15621461fb0c52675eba2b650492ed1beef69ab F src/malloc.c cc015821ba267ad5c91dc8761d0498a3fc3ce6ce @@ -231,7 +231,7 @@ F src/shell.c c00220cdd7f2027780bc25b78376c16dc24e4b7d F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 0f6bd5c2bc864b1261898a73673bed1030cfbfe2 +F src/sqliteInt.h e9030816d5ee6fe2063553b40359096f994664ee F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 218ae2ba022881846741dfc8351aefdf129e0377 @@ -282,7 +282,7 @@ F src/test_vfs.c f84075a388527892ff184988f43b69ce69b8083c F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 22dded4283dc4b25422f6444cdcb8d6b1ea0b5ff -F src/tokenize.c 722872c816887fd66931333c59570ebd9622a95f +F src/tokenize.c 3df63041994f55afeb168b463ec836e8f1c50e7c F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359 @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7e4978c003867d1b532b69221013dda75ca61953 -R 5b504a805873df7c692d762cd653895b +P 34292b084ef48cd6e9ca5704f6b072a29733b4c2 +R 9210ace0d122525851cce20a27ee9393 U drh -Z 9235587180e257c32aca7830c18cbf2e +Z 8a9f5697995e1302a3aaac24500097fb diff --git a/manifest.uuid b/manifest.uuid index 1b709cc082..2828da8f81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34292b084ef48cd6e9ca5704f6b072a29733b4c2 \ No newline at end of file +2f69a1fa6adc9377149ae7faa586a5d30b6a631b \ No newline at end of file diff --git a/src/lempar.c b/src/lempar.c index 2afaa6cea6..ba0837c0ab 100644 --- a/src/lempar.c +++ b/src/lempar.c @@ -271,9 +271,9 @@ static void yyGrowStack(yyParser *p){ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ -void *ParseAlloc(void *(*mallocProc)(size_t)){ +void *ParseAlloc(void *(*mallocProc)(u64)){ yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); + pParser = (yyParser*)(*mallocProc)( (u64)sizeof(yyParser) ); if( pParser ){ pParser->yyidx = -1; #ifdef YYTRACKMAXSTACKDEPTH diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e1faccb211..a254796abd 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3520,7 +3520,7 @@ int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); /* ** The interface to the LEMON-generated parser */ -void *sqlite3ParserAlloc(void*(*)(size_t)); +void *sqlite3ParserAlloc(void*(*)(u64)); void sqlite3ParserFree(void*, void(*)(void*)); void sqlite3Parser(void*, int, Token, Parse*); #ifdef YYTRACKMAXSTACKDEPTH diff --git a/src/tokenize.c b/src/tokenize.c index 3f1de221aa..8a7894514c 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -398,7 +398,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ pParse->zTail = zSql; i = 0; assert( pzErrMsg!=0 ); - pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc); + pEngine = sqlite3ParserAlloc(sqlite3Malloc); if( pEngine==0 ){ db->mallocFailed = 1; return SQLITE_NOMEM; From 236241aeb030ad3b23cea8a1f4d133e02f7dc60a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Sep 2014 17:41:30 +0000 Subject: [PATCH 26/30] Simplify the way the column cache is managed around OP_Move instructions. FossilOrigin-Name: 320556233e19cdd9d590a09655c3465754700d39 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 9 +-------- src/select.c | 4 ++-- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 4c19df8ec5..8501d7bcd0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sparser\smemory\sallocation\son\s32-bit\ssystems. -D 2014-09-12T04:28:33.110 +C Simplify\sthe\sway\sthe\scolumn\scache\sis\smanaged\saround\sOP_Move\sinstructions. +D 2014-09-12T17:41:30.440 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/ctime.c 16cd19215d9fd849ee2b7509b092f2e0bbd6a958 F src/date.c 57a7f9ba9f6b4d5268f5e411739066a611f99036 F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f -F src/expr.c 441a7e24e2f7bea9475778fa8acce9e8a69ca8f0 +F src/expr.c 19392d98e089640c3336e65b4254cc337efef7d1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 F src/func.c d4d218704b13bc1814b7d76874e405743c903773 @@ -226,7 +226,7 @@ F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c b4457526cee73c0b69fad42f799f619b1d5a8a8a +F src/select.c bd8ed75592642f79871fd331d869c37fc6a14846 F src/shell.c c00220cdd7f2027780bc25b78376c16dc24e4b7d F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 34292b084ef48cd6e9ca5704f6b072a29733b4c2 -R 9210ace0d122525851cce20a27ee9393 +P 2f69a1fa6adc9377149ae7faa586a5d30b6a631b +R 2196198b201612a018f7c15a4c2f1424 U drh -Z 8a9f5697995e1302a3aaac24500097fb +Z a609740927532bd8f27cb3bc904eb4ff diff --git a/manifest.uuid b/manifest.uuid index 2828da8f81..2b28a6b8f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f69a1fa6adc9377149ae7faa586a5d30b6a631b \ No newline at end of file +320556233e19cdd9d590a09655c3465754700d39 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index cd0983c579..c6d8b9e5f3 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2432,16 +2432,9 @@ void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ ** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. */ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ - int i; - struct yColCache *p; assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); - for(i=0, p=pParse->aColCache; iiReg; - if( x>=iFrom && xiReg += iTo-iFrom; - } - } + sqlite3ExprCacheRemove(pParse, iFrom, nReg); } #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) diff --git a/src/select.c b/src/select.c index 31a70bff1b..7ecbf30697 100644 --- a/src/select.c +++ b/src/select.c @@ -488,7 +488,7 @@ static void pushOntoSorter( sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); } if( nPrefixReg==0 ){ - sqlite3VdbeAddOp3(v, OP_Move, regData, regBase+nExpr+bSeq, nData); + sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); } sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord); @@ -524,7 +524,7 @@ static void pushOntoSorter( sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); sqlite3VdbeJumpHere(v, addrFirst); - sqlite3VdbeAddOp3(v, OP_Move, regBase, regPrevKey, pSort->nOBSat); + sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); sqlite3VdbeJumpHere(v, addrJmp); } if( pSort->sortFlags & SORTFLAG_UseSorter ){ From 36ce91913c7923e06f1b6cdb8385812fd0fe9998 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Sep 2014 20:30:59 +0000 Subject: [PATCH 27/30] Small performance improvement to the dirty list handling in the pager. FossilOrigin-Name: b332a84d5154f70f3197537df4af243eaebbb011 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 8501d7bcd0..81daedebde 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sway\sthe\scolumn\scache\sis\smanaged\saround\sOP_Move\sinstructions. -D 2014-09-12T17:41:30.440 +C Small\sperformance\simprovement\sto\sthe\sdirty\slist\shandling\sin\sthe\spager. +D 2014-09-12T20:30:59.762 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/pager.c c6c809987f0c6a4e27634099d062d425527de173 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 -F src/pcache.c 2048affdb09a04478b5fc6e64cb1083078d369be +F src/pcache.c b42c513da255c33e99dc0e23d16c3caf30dc9175 F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2f69a1fa6adc9377149ae7faa586a5d30b6a631b -R 2196198b201612a018f7c15a4c2f1424 +P 320556233e19cdd9d590a09655c3465754700d39 +R 576d19acba6677524711080ef6f39102 U drh -Z a609740927532bd8f27cb3bc904eb4ff +Z 60cbf2357ae42b4a38f44133d16be246 diff --git a/manifest.uuid b/manifest.uuid index 2b28a6b8f4..7821ed52ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -320556233e19cdd9d590a09655c3465754700d39 \ No newline at end of file +b332a84d5154f70f3197537df4af243eaebbb011 \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index 801df2b02a..e975e43889 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -116,14 +116,14 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ if( pPage->pDirtyNext ){ assert( pPage->pDirtyNext->pDirtyPrev==0 ); pPage->pDirtyNext->pDirtyPrev = pPage; - }else if( p->bPurgeable ){ - assert( p->eCreate==2 ); - p->eCreate = 1; + }else{ + p->pDirtyTail = pPage; + if( p->bPurgeable ){ + assert( p->eCreate==2 ); + p->eCreate = 1; + } } p->pDirty = pPage; - if( !p->pDirtyTail ){ - p->pDirtyTail = pPage; - } if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ p->pSynced = pPage; } @@ -399,7 +399,7 @@ void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ p->pCache->nRef--; if( (p->flags&PGHDR_DIRTY)==0 ){ pcacheUnpin(p); - }else{ + }else if( p->pDirtyPrev!=0 ){ /* Move the page to the head of the dirty list. */ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); } From 6092d2bcfebf699c970146308f910cb4f9423ace Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 15 Sep 2014 11:14:50 +0000 Subject: [PATCH 28/30] Adjust comments to show that subquery flattening restriction (10) was removed from the code back in 2005. This is a comment change only. FossilOrigin-Name: 4ff0eb96bc364baed2d8005c69291ca9240b99dd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 81daedebde..160c3f8d2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\simprovement\sto\sthe\sdirty\slist\shandling\sin\sthe\spager. -D 2014-09-12T20:30:59.762 +C Adjust\scomments\sto\sshow\sthat\ssubquery\sflattening\srestriction\s(10)\swas\nremoved\sfrom\sthe\scode\sback\sin\s2005.\s\sThis\sis\sa\scomment\schange\sonly. +D 2014-09-15T11:14:50.871 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -226,7 +226,7 @@ F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c bd8ed75592642f79871fd331d869c37fc6a14846 +F src/select.c 70312b18bf56f741556ed494c398afa0ca3c0e1a F src/shell.c c00220cdd7f2027780bc25b78376c16dc24e4b7d F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 320556233e19cdd9d590a09655c3465754700d39 -R 576d19acba6677524711080ef6f39102 +P b332a84d5154f70f3197537df4af243eaebbb011 +R 4fde0e674c64eada90bf3beabe45d5b4 U drh -Z 60cbf2357ae42b4a38f44133d16be246 +Z 7e796116236157f7f97effb3ae76fb8a diff --git a/manifest.uuid b/manifest.uuid index 7821ed52ba..30c79b290d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b332a84d5154f70f3197537df4af243eaebbb011 \ No newline at end of file +4ff0eb96bc364baed2d8005c69291ca9240b99dd \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7ecbf30697..fe6052d6e8 100644 --- a/src/select.c +++ b/src/select.c @@ -3131,8 +3131,10 @@ static void substSelect( ** (9) The subquery does not use LIMIT or the outer query does not use ** aggregates. ** -** (10) The subquery does not use aggregates or the outer query does not -** use LIMIT. +** (**) Restriction (10) was removed from the code on 2005-02-05 but we +** accidently carried the comment forward until 2014-09-15. Original +** text: "The subquery does not use aggregates or the outer query does not +** use LIMIT." ** ** (11) The subquery and the outer query do not both have ORDER BY clauses. ** From 9588ad95c1a9cc7cd5add559b43536d48a4f2e4e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 15 Sep 2014 14:46:02 +0000 Subject: [PATCH 29/30] Do not flatten aggregate subqueries that contain min() or max() functions so that if the min()/max() are discarded by the outer query, they still function and cause non-aggregate expression to be evaluated on the minimal or maximal row. FossilOrigin-Name: 0bdf1a086b3946722f4d4b328e25917f61c14713 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/func.c | 10 ++++++---- src/resolve.c | 24 ++++++++++++++---------- src/select.c | 15 +++++++++++++-- src/sqliteInt.h | 25 +++++++++++++++++-------- test/aggnested.test | 8 +++++++- test/minmax4.test | 9 ++++++--- 8 files changed, 75 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index 160c3f8d2f..f13c9ab026 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\scomments\sto\sshow\sthat\ssubquery\sflattening\srestriction\s(10)\swas\nremoved\sfrom\sthe\scode\sback\sin\s2005.\s\sThis\sis\sa\scomment\schange\sonly. -D 2014-09-15T11:14:50.871 +C Do\snot\sflatten\saggregate\ssubqueries\sthat\scontain\smin()\sor\smax()\sfunctions\nso\sthat\sif\sthe\smin()/max()\sare\sdiscarded\sby\sthe\souter\squery,\sthey\sstill\nfunction\sand\scause\snon-aggregate\sexpression\sto\sbe\sevaluated\son\sthe\sminimal\nor\smaximal\srow. +D 2014-09-15T14:46:02.082 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/delete.c fae81cc2eb14b75267d4f47d3cfc9ae02aae726f F src/expr.c 19392d98e089640c3336e65b4254cc337efef7d1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 -F src/func.c d4d218704b13bc1814b7d76874e405743c903773 +F src/func.c 5d498933f6168dff80941c873805fe04dc2b766d F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -224,14 +224,14 @@ F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196 F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece -F src/resolve.c 0d1621e45fffe4b4396477cf46e41a84b0145ffb +F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 70312b18bf56f741556ed494c398afa0ca3c0e1a +F src/select.c 0cd6706fd52ae5db229e9041094db6ec27195335 F src/shell.c c00220cdd7f2027780bc25b78376c16dc24e4b7d F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h e9030816d5ee6fe2063553b40359096f994664ee +F src/sqliteInt.h 0803e900eb1882f7dd88e86ddcddd2d1b27c8d86 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 218ae2ba022881846741dfc8351aefdf129e0377 @@ -305,7 +305,7 @@ F src/where.c 839b5e1db2507e221ad1c308f148a8519ed750be F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 -F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 +F test/aggnested.test b35b4cd69fc913f90d39a575e171e1116c3a4bb7 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 6ff7b43c2b4b905c74dc4a813d201d0fa64c5783 F test/alter.test 547dc2d292644301ac9a7dda22b319b74f9c08d2 @@ -712,7 +712,7 @@ F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 -F test/minmax4.test 536a3360470633a177e42fbc19660d146b51daef +F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f F test/misc1.test 1201a037c24f982cc0e956cdaa34fcaf6439c417 F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b332a84d5154f70f3197537df4af243eaebbb011 -R 4fde0e674c64eada90bf3beabe45d5b4 +P 4ff0eb96bc364baed2d8005c69291ca9240b99dd +R d83c0c27bf862a8b9f30cb2ccec5fde3 U drh -Z 7e796116236157f7f97effb3ae76fb8a +Z 5049f8c8dea35bd8f91ea699f6fd9960 diff --git a/manifest.uuid b/manifest.uuid index 30c79b290d..69d001e682 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ff0eb96bc364baed2d8005c69291ca9240b99dd \ No newline at end of file +0bdf1a086b3946722f4d4b328e25917f61c14713 \ No newline at end of file diff --git a/src/func.c b/src/func.c index f7e50f3374..0a8a9dda38 100644 --- a/src/func.c +++ b/src/func.c @@ -1663,10 +1663,12 @@ void sqlite3RegisterGlobalFunctions(void){ FUNCTION(trim, 2, 3, 0, trimFunc ), FUNCTION(min, -1, 0, 1, minmaxFunc ), FUNCTION(min, 0, 0, 1, 0 ), - AGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize ), + AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize, + SQLITE_FUNC_MINMAX ), FUNCTION(max, -1, 1, 1, minmaxFunc ), FUNCTION(max, 0, 1, 1, 0 ), - AGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize ), + AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize, + SQLITE_FUNC_MINMAX ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), FUNCTION(instr, 2, 0, 0, instrFunc ), @@ -1719,8 +1721,8 @@ void sqlite3RegisterGlobalFunctions(void){ AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), - /* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */ - {0,SQLITE_UTF8|SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0}, + AGGREGATE2(count, 0, 0, 0, countStep, countFinalize, + SQLITE_FUNC_COUNT ), AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), diff --git a/src/resolve.c b/src/resolve.c index a77fd9d367..d6a865caef 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -719,9 +719,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938; } } - } #ifndef SQLITE_OMIT_AUTHORIZATION - if( pDef ){ auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0); if( auth!=SQLITE_OK ){ if( auth==SQLITE_DENY ){ @@ -732,9 +730,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->op = TK_NULL; return WRC_Prune; } +#endif if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); } -#endif if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); pNC->nErr++; @@ -757,7 +755,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->op2++; pNC2 = pNC2->pNext; } - if( pNC2 ) pNC2->ncFlags |= NC_HasAgg; + assert( pDef!=0 ); + if( pNC2 ){ + assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); + pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); + + } pNC->ncFlags |= NC_AllowAgg; } /* FIX ME: Compute pExpr->affinity based on the expected return @@ -1222,7 +1226,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ assert( (p->selFlags & SF_Aggregate)==0 ); pGroupBy = p->pGroupBy; if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ - p->selFlags |= SF_Aggregate; + assert( NC_MinMaxAgg==SF_MinMaxAgg ); + p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg); }else{ sNC.ncFlags &= ~NC_AllowAgg; } @@ -1350,7 +1355,7 @@ int sqlite3ResolveExprNames( NameContext *pNC, /* Namespace to resolve expressions in. */ Expr *pExpr /* The expression to be analyzed. */ ){ - u8 savedHasAgg; + u16 savedHasAgg; Walker w; if( pExpr==0 ) return 0; @@ -1363,8 +1368,8 @@ int sqlite3ResolveExprNames( pParse->nHeight += pExpr->nHeight; } #endif - savedHasAgg = pNC->ncFlags & NC_HasAgg; - pNC->ncFlags &= ~NC_HasAgg; + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg); memset(&w, 0, sizeof(w)); w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; @@ -1379,9 +1384,8 @@ int sqlite3ResolveExprNames( } if( pNC->ncFlags & NC_HasAgg ){ ExprSetProperty(pExpr, EP_Agg); - }else if( savedHasAgg ){ - pNC->ncFlags |= NC_HasAgg; } + pNC->ncFlags |= savedHasAgg; return ExprHasProperty(pExpr, EP_Error); } diff --git a/src/select.c b/src/select.c index fe6052d6e8..d3ffaf451a 100644 --- a/src/select.c +++ b/src/select.c @@ -3197,6 +3197,11 @@ static void substSelect( ** parent to a compound query confuses the code that handles ** recursive queries in multiSelect(). ** +** (24) The subquery is not an aggregate that uses the built-in min() or +** or max() functions. (Without this restriction, a query like: +** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily +** return the value X for which Y was maximal.) +** ** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query @@ -3269,8 +3274,14 @@ static int flattenSubquery( if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){ return 0; /* Restriction (21) */ } - if( pSub->selFlags & SF_Recursive ) return 0; /* Restriction (22) */ - if( (p->selFlags & SF_Recursive) && pSub->pPrior ) return 0; /* (23) */ + testcase( pSub->selFlags & SF_Recursive ); + testcase( pSub->selFlags & SF_MinMaxAgg ); + if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){ + return 0; /* Restrictions (22) and (24) */ + } + if( (p->selFlags & SF_Recursive) && pSub->pPrior ){ + return 0; /* Restriction (23) */ + } /* OBSOLETE COMMENT 1: ** Restriction 3: If the subquery is a join, make sure the subquery is diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a254796abd..fd3731d817 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1285,6 +1285,7 @@ struct FuncDestructor { #define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */ #define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */ #define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */ +#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -1332,6 +1333,9 @@ struct FuncDestructor { #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} +#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ + {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ + SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} /* ** All current savepoints are stored in a linked list starting at @@ -2254,17 +2258,22 @@ struct NameContext { NameContext *pNext; /* Next outer name context. NULL for outermost */ int nRef; /* Number of names resolved by this context */ int nErr; /* Number of errors encountered while resolving names */ - u8 ncFlags; /* Zero or more NC_* flags defined below */ + u16 ncFlags; /* Zero or more NC_* flags defined below */ }; /* ** Allowed values for the NameContext, ncFlags field. +** +** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and +** SQLITE_FUNC_MINMAX. +** */ -#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */ -#define NC_HasAgg 0x02 /* One or more aggregate functions seen */ -#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */ -#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */ -#define NC_PartIdx 0x10 /* True if resolving a partial index WHERE */ +#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */ +#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */ +#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */ +#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */ +#define NC_PartIdx 0x0010 /* True if resolving a partial index WHERE */ +#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ /* ** An instance of the following structure contains all information @@ -2315,13 +2324,13 @@ struct Select { #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */ #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */ - /* 0x0040 NOT USED */ +#define SF_Compound 0x0040 /* Part of a compound query */ #define SF_Values 0x0080 /* Synthesized from VALUES clause */ /* 0x0100 NOT USED */ #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */ #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */ #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */ -#define SF_Compound 0x1000 /* Part of a compound query */ +#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */ /* diff --git a/test/aggnested.test b/test/aggnested.test index 6e2fd6554b..a87c751eda 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -156,8 +156,14 @@ do_test aggnested-3.2 { (SELECT value1 as xyz, max(x1) AS pqr FROM t1 GROUP BY id1); + SELECT + (SELECT sum(value2<>xyz) FROM t2) + FROM + (SELECT value1 as xyz, max(x1) AS pqr + FROM t1 + GROUP BY id1); } -} {0} +} {1 0} do_test aggnested-3.3 { db eval { DROP TABLE IF EXISTS t1; diff --git a/test/minmax4.test b/test/minmax4.test index 0d8305b5ff..8063538bfd 100644 --- a/test/minmax4.test +++ b/test/minmax4.test @@ -56,14 +56,16 @@ do_test minmax4-1.5 { do_test minmax4-1.6 { db eval { SELECT p, min(q) FROM t1; + SELECT p FROM (SELECT p, min(q) FROM t1); } -} {1 2} +} {1 2 1} do_test minmax4-1.7 { db eval { INSERT INTO t1 VALUES(5,0); SELECT p, max(q) FROM t1; + SELECT p FROM (SELECT max(q), p FROM t1); } -} {3 4} +} {3 4 3} do_test minmax4-1.8 { db eval { SELECT p, min(q) FROM t1; @@ -73,8 +75,9 @@ do_test minmax4-1.9 { db eval { INSERT INTO t1 VALUES(6,1); SELECT p, max(q) FROM t1; + SELECT p FROM (SELECT max(q), p FROM t1); } -} {3 4} +} {3 4 3} do_test minmax4-1.10 { db eval { SELECT p, min(q) FROM t1; From 907214c8e83a3d1f35b6cce5768016089193b3c2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 15 Sep 2014 14:59:12 +0000 Subject: [PATCH 30/30] Remove the EXPENSIVE_ASSERTS in pcache.c having to do with the pSynced field of the Pcache object, as they are incorrect, as revealed by recent pcache enhancements. FossilOrigin-Name: 69a64560777f85b47349b4b2aab01dc99298592e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache.c | 20 -------------------- 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index f13c9ab026..7e35806fec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sflatten\saggregate\ssubqueries\sthat\scontain\smin()\sor\smax()\sfunctions\nso\sthat\sif\sthe\smin()/max()\sare\sdiscarded\sby\sthe\souter\squery,\sthey\sstill\nfunction\sand\scause\snon-aggregate\sexpression\sto\sbe\sevaluated\son\sthe\sminimal\nor\smaximal\srow. -D 2014-09-15T14:46:02.082 +C Remove\sthe\sEXPENSIVE_ASSERTS\sin\spcache.c\shaving\sto\sdo\swith\sthe\spSynced\sfield\nof\sthe\sPcache\sobject,\sas\sthey\sare\sincorrect,\sas\srevealed\sby\srecent\spcache\nenhancements. +D 2014-09-15T14:59:12.274 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -217,7 +217,7 @@ F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/pager.c c6c809987f0c6a4e27634099d062d425527de173 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 -F src/pcache.c b42c513da255c33e99dc0e23d16c3caf30dc9175 +F src/pcache.c 4121a0571c18581ee9f82f086d5e2030051ebd6a F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f @@ -1197,7 +1197,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4ff0eb96bc364baed2d8005c69291ca9240b99dd -R d83c0c27bf862a8b9f30cb2ccec5fde3 +P 0bdf1a086b3946722f4d4b328e25917f61c14713 +R 6604c3404d8f943a6eb10e6ee4c1398f U drh -Z 5049f8c8dea35bd8f91ea699f6fd9960 +Z 9f457bfb74de1e07b081e001cb58874a diff --git a/manifest.uuid b/manifest.uuid index 69d001e682..0cb3407f29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0bdf1a086b3946722f4d4b328e25917f61c14713 \ No newline at end of file +69a64560777f85b47349b4b2aab01dc99298592e \ No newline at end of file diff --git a/src/pcache.c b/src/pcache.c index e975e43889..191a9d00f4 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -45,23 +45,6 @@ struct PCache { /********************************** Linked List Management ********************/ -#if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) -/* -** Check that the pCache->pSynced variable is set correctly. If it -** is not, either fail an assert or return zero. Otherwise, return -** non-zero. This is only used in debugging builds, as follows: -** -** expensive_assert( pcacheCheckSynced(pCache) ); -*/ -static int pcacheCheckSynced(PCache *pCache){ - PgHdr *p; - for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pDirtyPrev){ - assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) ); - } - return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0); -} -#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */ - /* Allowed values for second argument to pcacheManageDirtyList() */ #define PCACHE_DIRTYLIST_REMOVE 1 /* Remove pPage from dirty list */ #define PCACHE_DIRTYLIST_ADD 2 /* Add pPage to the dirty list */ @@ -107,7 +90,6 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ } pPage->pDirtyNext = 0; pPage->pDirtyPrev = 0; - expensive_assert( pcacheCheckSynced(p) ); } if( addRemove & PCACHE_DIRTYLIST_ADD ){ assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage ); @@ -127,7 +109,6 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){ p->pSynced = pPage; } - expensive_assert( pcacheCheckSynced(p) ); } } @@ -304,7 +285,6 @@ int sqlite3PcacheFetchStress( ** cleared), but if that is not possible settle for any other ** unreferenced dirty page. */ - expensive_assert( pcacheCheckSynced(pCache) ); for(pPg=pCache->pSynced; pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); pPg=pPg->pDirtyPrev