From d45309796bac57233a063af72f0ac5a08bde8a04 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Sep 2014 14:47:53 +0000 Subject: [PATCH 01/65] 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 02/65] 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 03/65] 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 04/65] 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 05/65] 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 06/65] 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 07/65] 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 08/65] 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 09/65] 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 10/65] 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 11/65] 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 12/65] 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 13/65] 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 14/65] 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 15/65] 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 16/65] 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 17/65] 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 18/65] 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 19/65] 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 20/65] 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 21/65] 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 22/65] 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 23/65] 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 From ed7bcba7980a59d400b592e7306d72e1599678fd Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 15 Sep 2014 16:50:34 +0000 Subject: [PATCH 24/65] Avoid attempting to call the xFetch() method of an sqlite3_io_methods object with a version number less than 3. FossilOrigin-Name: dedaa6fb3d2e6e697d4a48649af5f42d9a11c333 --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/vdbesort.c | 9 ++++++--- test/sort5.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 test/sort5.test diff --git a/manifest b/manifest index 7e35806fec..bf269d15d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 +C Avoid\sattempting\sto\scall\sthe\sxFetch()\smethod\sof\san\ssqlite3_io_methods\sobject\swith\sa\sversion\snumber\sless\sthan\s3. +D 2014-09-15T16:50:34.423 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -295,7 +295,7 @@ F src/vdbeapi.c 06b712d4772b318b69cd37a416deb1ff0426aa8c F src/vdbeaux.c 91fd1e0c54a765838dc61fcf79f31acce035ce38 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a -F src/vdbesort.c ab39574ec6e0c6213bd2a5c09cca9f9f8ba98450 +F src/vdbesort.c a7a40ceca6325b853040ffcc363dcd49a45f201b F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983 @@ -845,6 +845,7 @@ F test/sort.test 15e1d3014abc3f6d4357ed81b93b82117aefd235 F test/sort2.test 269f4f50c6e468cc32b302ae7ff0add8338ec6de F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2 F test/sort4.test 6c37d85f7cd28d50cce222fcab84ccd771e105cb +F test/sort5.test a448240a42b49239edc00f85d6d7ac7a1b261e1f F test/sortfault.test b8e35177f97438b930ee87c9419ca2599e8073e1 F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb @@ -1197,7 +1198,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 0bdf1a086b3946722f4d4b328e25917f61c14713 -R 6604c3404d8f943a6eb10e6ee4c1398f -U drh -Z 9f457bfb74de1e07b081e001cb58874a +P 69a64560777f85b47349b4b2aab01dc99298592e +R 41452df15ff1b435df3a846f31103df4 +U dan +Z 356b29f991ba0eb562f8fca4ef2b2ea4 diff --git a/manifest.uuid b/manifest.uuid index 0cb3407f29..13bc35293d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69a64560777f85b47349b4b2aab01dc99298592e \ No newline at end of file +dedaa6fb3d2e6e697d4a48649af5f42d9a11c333 \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index d1ccf6089d..b9a62bf569 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -602,8 +602,11 @@ static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){ int rc = SQLITE_OK; if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){ - rc = sqlite3OsFetch(pFile->pFd, 0, (int)pFile->iEof, (void**)pp); - testcase( rc!=SQLITE_OK ); + sqlite3_file *pFd = pFile->pFd; + if( pFd->pMethods->iVersion>=3 ){ + rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp); + testcase( rc!=SQLITE_OK ); + } } return rc; } @@ -1123,7 +1126,7 @@ void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ if( nByte<=(i64)(db->nMaxSorterMmap) ){ int rc = sqlite3OsTruncate(pFd, nByte); - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && pFd->pMethods->iVersion>=3 ){ void *p = 0; sqlite3OsFetch(pFd, 0, (int)nByte, &p); sqlite3OsUnfetch(pFd, 0, p); diff --git a/test/sort5.test b/test/sort5.test new file mode 100644 index 0000000000..a02b8f920f --- /dev/null +++ b/test/sort5.test @@ -0,0 +1,45 @@ +# 2014 September 15. +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix sort5 + + +#------------------------------------------------------------------------- +# Verify that sorting works with a version 1 sqlite3_io_methods structure. +# +testvfs tvfs -iversion 1 -default true +reset_db +do_execsql_test 1.0 { + PRAGMA mmap_size = 10000000; + PRAGMA cache_size = 10; + CREATE TABLE t1(a, b); +} {0} + +do_test 1.1 { + execsql BEGIN + for {set i 0} {$i < 2000} {incr i} { + execsql { INSERT INTO t1 VALUES($i, randomblob(2000)) } + } + execsql COMMIT +} {} + +do_execsql_test 1.2 { + CREATE INDEX i1 ON t1(b); +} + +db close +tvfs delete +finish_test + From b6dea49f3d30bd348676eb5c6795f6f1ea5c173c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 15 Sep 2014 16:53:23 +0000 Subject: [PATCH 25/65] Fix tool/showwal.c so that it handles WAL files that contain 64KiB pages. FossilOrigin-Name: 4060efb646c873c4abde7ab9ddf330489a44f274 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/showwal.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index bf269d15d0..44c6f5bfa6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sattempting\sto\scall\sthe\sxFetch()\smethod\sof\san\ssqlite3_io_methods\sobject\swith\sa\sversion\snumber\sless\sthan\s3. -D 2014-09-15T16:50:34.423 +C Fix\stool/showwal.c\sso\sthat\sit\shandles\sWAL\sfiles\sthat\scontain\s64KiB\spages. +D 2014-09-15T16:53:23.593 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1179,7 +1179,7 @@ F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/showdb.c bd073a78bce714a0e42d92ea474b3eb8cb53be5d F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5 F tool/showstat4.c c39279d6bd37cb999b634f0064f6f86ad7af008f -F tool/showwal.c 3209120269cdf9380f091459e47b776b4f81dfd3 +F tool/showwal.c 85cb36d4fe3e93e2fbd63e786e0d1ce42d0c4fad F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b F tool/spaceanal.tcl 8e50b217c56a6a086a1b47eac9d09c5cd65b996f @@ -1198,7 +1198,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 69a64560777f85b47349b4b2aab01dc99298592e -R 41452df15ff1b435df3a846f31103df4 +P dedaa6fb3d2e6e697d4a48649af5f42d9a11c333 +R 9c897c2b35082efdf1b1cdba3d9a6e48 U dan -Z 356b29f991ba0eb562f8fca4ef2b2ea4 +Z fbf2bdf01c7200ebedc4b699448a8435 diff --git a/manifest.uuid b/manifest.uuid index 13bc35293d..f4f07abe9e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dedaa6fb3d2e6e697d4a48649af5f42d9a11c333 \ No newline at end of file +4060efb646c873c4abde7ab9ddf330489a44f274 \ No newline at end of file diff --git a/tool/showwal.c b/tool/showwal.c index 6dc1de173f..35810c66a9 100644 --- a/tool/showwal.c +++ b/tool/showwal.c @@ -510,7 +510,7 @@ static void decode_btree_page( int main(int argc, char **argv){ struct stat sbuf; - unsigned char zPgSz[2]; + unsigned char zPgSz[4]; if( argc<2 ){ fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]); exit(1); @@ -522,9 +522,9 @@ int main(int argc, char **argv){ } zPgSz[0] = 0; zPgSz[1] = 0; - lseek(fd, 10, SEEK_SET); - read(fd, zPgSz, 2); - pagesize = zPgSz[0]*256 + zPgSz[1]; + lseek(fd, 8, SEEK_SET); + read(fd, zPgSz, 4); + pagesize = zPgSz[1]*65536 + zPgSz[2]*256 + zPgSz[3]; if( pagesize==0 ) pagesize = 1024; printf("Pagesize: %d\n", pagesize); fstat(fd, &sbuf); From 982ff72f0f90e9bc5bc314482e6fba1cc4ca2579 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 03:24:43 +0000 Subject: [PATCH 26/65] Performance improvement to the sqlite3MemCompare() routine by factoring out sqlite3BlobCompare(). FossilOrigin-Name: 20ed2321b09ba076e50f9fc2f42c135b25746d72 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 19 +++++++++++++------ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 44c6f5bfa6..8a0b3a189a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stool/showwal.c\sso\sthat\sit\shandles\sWAL\sfiles\sthat\scontain\s64KiB\spages. -D 2014-09-15T16:53:23.593 +C Performance\simprovement\sto\sthe\ssqlite3MemCompare()\sroutine\sby\sfactoring\sout\nsqlite3BlobCompare(). +D 2014-09-16T03:24:43.248 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -292,7 +292,7 @@ F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h b4843c35c3ba533b69d4250f550b5bacf2fb013d F src/vdbeapi.c 06b712d4772b318b69cd37a416deb1ff0426aa8c -F src/vdbeaux.c 91fd1e0c54a765838dc61fcf79f31acce035ce38 +F src/vdbeaux.c cde99fa6659f5f9000d2d84bb5c4cc85d9e0a200 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a F src/vdbesort.c a7a40ceca6325b853040ffcc363dcd49a45f201b @@ -1198,7 +1198,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 dedaa6fb3d2e6e697d4a48649af5f42d9a11c333 -R 9c897c2b35082efdf1b1cdba3d9a6e48 -U dan -Z fbf2bdf01c7200ebedc4b699448a8435 +P 4060efb646c873c4abde7ab9ddf330489a44f274 +R 2d14ce03cde1c84220e0226983629fd3 +U drh +Z 10220c87d8978c341785bd01c3f5069d diff --git a/manifest.uuid b/manifest.uuid index f4f07abe9e..bbfe9273dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4060efb646c873c4abde7ab9ddf330489a44f274 \ No newline at end of file +20ed2321b09ba076e50f9fc2f42c135b25746d72 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a653587319..86f36aba87 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3319,6 +3319,18 @@ static int vdbeCompareMemString( } } +/* +** Compare two blobs. Return negative, zero, or positive if the first +** is less than, equal to, or greater than the second, respectively. +** If one blob is a prefix of the other, then the shorter is the lessor. +*/ +static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ + int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n); + if( c ) return c; + return pB1->n - pB2->n; +} + + /* ** Compare the values contained by the two memory cells, returning ** negative, zero or positive if pMem1 is less than, equal to, or greater @@ -3329,7 +3341,6 @@ static int vdbeCompareMemString( ** Two NULL values are considered equal by this function. */ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ - int rc; int f1, f2; int combined_flags; @@ -3404,11 +3415,7 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ } /* Both values must be blobs. Compare using memcmp(). */ - rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n); - if( rc==0 ){ - rc = pMem1->n - pMem2->n; - } - return rc; + return sqlite3BlobCompare(pMem1, pMem2); } From 7f4b19f170ff8010cd88c248aa9bf7b909d1dc75 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 13:30:05 +0000 Subject: [PATCH 27/65] Changes to sqlite3VdbeRecordUnpack() to make it slightly smaller and faster. FossilOrigin-Name: 8fb90da77ce0e662c1ef1ae0d854e5164494b7af --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8a0b3a189a..6eff938f17 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sto\sthe\ssqlite3MemCompare()\sroutine\sby\sfactoring\sout\nsqlite3BlobCompare(). -D 2014-09-16T03:24:43.248 +C Changes\sto\ssqlite3VdbeRecordUnpack()\sto\smake\sit\sslightly\ssmaller\sand\sfaster. +D 2014-09-16T13:30:05.468 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -292,7 +292,7 @@ F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h b4843c35c3ba533b69d4250f550b5bacf2fb013d F src/vdbeapi.c 06b712d4772b318b69cd37a416deb1ff0426aa8c -F src/vdbeaux.c cde99fa6659f5f9000d2d84bb5c4cc85d9e0a200 +F src/vdbeaux.c 2f284f8b052acc5b484682fbd3de35c990c2ca1c F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a F src/vdbesort.c a7a40ceca6325b853040ffcc363dcd49a45f201b @@ -1198,7 +1198,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 4060efb646c873c4abde7ab9ddf330489a44f274 -R 2d14ce03cde1c84220e0226983629fd3 +P 20ed2321b09ba076e50f9fc2f42c135b25746d72 +R 052add0d7794460f3fc0b9bdb3e7879a U drh -Z 10220c87d8978c341785bd01c3f5069d +Z bf1aaf6028da77cf4241e813f52ee696 diff --git a/manifest.uuid b/manifest.uuid index bbfe9273dd..d8ad59bb30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20ed2321b09ba076e50f9fc2f42c135b25746d72 \ No newline at end of file +8fb90da77ce0e662c1ef1ae0d854e5164494b7af \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 86f36aba87..3360d919b2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3161,7 +3161,7 @@ void sqlite3VdbeRecordUnpack( idx = getVarint32(aKey, szHdr); d = szHdr; u = 0; - while( idxnField && d<=nKey ){ + while( idxzMalloc = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; - u++; + if( (++u)>=p->nField ) break; } assert( u<=pKeyInfo->nField + 1 ); p->nField = u; From 035e563bf62e749036825d85fdd885a4110810ce Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 14:16:31 +0000 Subject: [PATCH 28/65] Reorder the elements of the Mem object for a small size reduction and performance improvement. FossilOrigin-Name: 0be3019ed794c10de67dfd645ceea7d45815bc4b --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/func.c | 1 + src/vdbeInt.h | 13 +++++++------ src/vdbeapi.c | 16 +++++++++++++--- src/vdbeaux.c | 5 +++-- src/vdbemem.c | 2 ++ 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 6eff938f17..30bef2c31f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\ssqlite3VdbeRecordUnpack()\sto\smake\sit\sslightly\ssmaller\sand\sfaster. -D 2014-09-16T13:30:05.468 +C Reorder\sthe\selements\sof\sthe\sMem\sobject\sfor\sa\ssmall\ssize\sreduction\sand\nperformance\simprovement. +D 2014-09-16T14:16:31.846 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 5d498933f6168dff80941c873805fe04dc2b766d +F src/func.c 1629ccdd8ef3f19d7accc9d9287190489469ff81 F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -290,11 +290,11 @@ F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 -F src/vdbeInt.h b4843c35c3ba533b69d4250f550b5bacf2fb013d -F src/vdbeapi.c 06b712d4772b318b69cd37a416deb1ff0426aa8c -F src/vdbeaux.c 2f284f8b052acc5b484682fbd3de35c990c2ca1c +F src/vdbeInt.h 0de8705e38b5f28808e37cebb9ec6df995ac3304 +F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 +F src/vdbeaux.c 4d607ce804cc4ee129df5745f7b73ed472f808b6 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c dc36ea9fe26c25550c50085f388167086ef7d73a +F src/vdbemem.c 4d1e1398be24f85805196c20a80699be0699a9ca F src/vdbesort.c a7a40ceca6325b853040ffcc363dcd49a45f201b F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 20ed2321b09ba076e50f9fc2f42c135b25746d72 -R 052add0d7794460f3fc0b9bdb3e7879a +P 8fb90da77ce0e662c1ef1ae0d854e5164494b7af +R 66ed6d98b57d603d2a5f34403ecc91fe U drh -Z bf1aaf6028da77cf4241e813f52ee696 +Z d53857782fade1fcfcd0d6fed6dee986 diff --git a/manifest.uuid b/manifest.uuid index d8ad59bb30..d1ee51fd68 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8fb90da77ce0e662c1ef1ae0d854e5164494b7af \ No newline at end of file +0be3019ed794c10de67dfd645ceea7d45815bc4b \ No newline at end of file diff --git a/src/func.c b/src/func.c index 0a8a9dda38..e1961118fd 100644 --- a/src/func.c +++ b/src/func.c @@ -1492,6 +1492,7 @@ static void minmaxStep( sqlite3SkipAccumulatorLoad(context); } }else{ + pBest->db = sqlite3_context_db_handle(context); sqlite3VdbeMemCopy(pBest, pArg); } } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 27b266986a..5379d6b667 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -161,9 +161,6 @@ struct VdbeFrame { ** integer etc.) of the same value. */ struct Mem { - sqlite3 *db; /* The associated database connection */ - char *z; /* String or BLOB value */ - double r; /* Real value */ union { i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Used when bit MEM_Zero is set in flags */ @@ -171,15 +168,19 @@ struct Mem { RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; - int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ + int n; /* Number of characters in string value, excluding '\0' */ + double r; /* Real value */ + char *z; /* String or BLOB value */ + char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ + /* ShallowCopy only needs to copy the information above */ + sqlite3 *db; /* The associated database connection */ + void (*xDel)(void*);/* If not null, call this function to delete Mem.z */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ #endif - void (*xDel)(void *); /* If not null, call this function to delete Mem.z */ - char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ }; /* One or more of the following flags are set to indicate the validOK diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b64f33c8c6..14d6b8412e 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -803,11 +803,21 @@ static const Mem *columnNullValue(void){ #if defined(SQLITE_DEBUG) && defined(__GNUC__) __attribute__((aligned(8))) #endif - = {0, "", (double)0, {0}, 0, MEM_Null, 0, + = { + .flags = MEM_Null, + .enc = 0, + .n = 0, + .r = (double)0, + .u = {0}, + .z = 0, + .zMalloc = 0, + .db = 0, + .xDel = 0, #ifdef SQLITE_DEBUG - 0, 0, /* pScopyFrom, pFiller */ + .pScopyFrom = 0, + .pFiller = 0, #endif - 0, 0 }; + }; return &nullMem; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 3360d919b2..65792b485e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3303,8 +3303,9 @@ static int vdbeCompareMemString( int n1, n2; Mem c1; Mem c2; - memset(&c1, 0, sizeof(c1)); - memset(&c2, 0, sizeof(c2)); + c1.db = c2.db = pMem1->db; + c1.flags = c2.flags = 0; + c1.zMalloc = c2.zMalloc = 0; sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); diff --git a/src/vdbemem.c b/src/vdbemem.c index ea4def3f86..7785bc0de5 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -730,6 +730,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ */ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( (pFrom->flags & MEM_RowSet)==0 ); + assert( pTo->db==pFrom->db ); VdbeMemReleaseExtern(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->xDel = 0; @@ -747,6 +748,7 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc = SQLITE_OK; + assert( pTo->db==pFrom->db ); assert( (pFrom->flags & MEM_RowSet)==0 ); VdbeMemReleaseExtern(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); From 75179ded976666932155d84f7ed805a8f6e167ca Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 14:37:35 +0000 Subject: [PATCH 29/65] Reduce the number of arguments to RecordCompare functions from 4 to 3, resulting in a small performance increase. FossilOrigin-Name: 8239c35aedd583af79505378bb7dbb78346a3f45 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/btree.c | 6 +++--- src/vdbe.h | 4 ++-- src/vdbeaux.c | 30 +++++++++++++++--------------- src/vdbesort.c | 4 ++-- src/where.c | 8 ++++---- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 30bef2c31f..154cd1a029 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reorder\sthe\selements\sof\sthe\sMem\sobject\sfor\sa\ssmall\ssize\sreduction\sand\nperformance\simprovement. -D 2014-09-16T14:16:31.846 +C Reduce\sthe\snumber\sof\sarguments\sto\sRecordCompare\sfunctions\sfrom\s4\sto\s3,\nresulting\sin\sa\ssmall\sperformance\sincrease. +D 2014-09-16T14:37:35.076 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -171,7 +171,7 @@ F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c e4916b441bb036897cc69df275a2df3fea4d53b6 +F src/btree.c 6aa61c0e3d20d1d1acc8fb33d8f0ebd675305d3c F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc F src/build.c 047d7e1d2d89fa55134fa1d6b669c9c2983c0d11 @@ -289,19 +289,19 @@ F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359 F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 -F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 +F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h 0de8705e38b5f28808e37cebb9ec6df995ac3304 F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 -F src/vdbeaux.c 4d607ce804cc4ee129df5745f7b73ed472f808b6 +F src/vdbeaux.c d06769a7c1f8db9c04fe1457d357203a06684662 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c 4d1e1398be24f85805196c20a80699be0699a9ca -F src/vdbesort.c a7a40ceca6325b853040ffcc363dcd49a45f201b +F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 839b5e1db2507e221ad1c308f148a8519ed750be +F src/where.c dc276288039fb45ce23c80e4535980f5a152d8ec F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1198,7 +1198,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 8fb90da77ce0e662c1ef1ae0d854e5164494b7af -R 66ed6d98b57d603d2a5f34403ecc91fe +P 0be3019ed794c10de67dfd645ceea7d45815bc4b +R 4ac54fa45280398cdbf86b6ba8db7793 U drh -Z d53857782fade1fcfcd0d6fed6dee986 +Z fba86109c421937fd36d2c7c73cc5fa1 diff --git a/manifest.uuid b/manifest.uuid index d1ee51fd68..d03654a7d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0be3019ed794c10de67dfd645ceea7d45815bc4b \ No newline at end of file +8239c35aedd583af79505378bb7dbb78346a3f45 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index fe34b4a836..522e945ac2 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4746,14 +4746,14 @@ int sqlite3BtreeMovetoUnpacked( ** single byte varint and the record fits entirely on the main ** b-tree page. */ testcase( pCell+nCell+1==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey, 0); + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal ){ /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ testcase( pCell+nCell+2==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey, 0); + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); }else{ /* The record flows over onto one or more overflow pages. In ** this case the whole cell needs to be parsed, a buffer allocated @@ -4774,7 +4774,7 @@ int sqlite3BtreeMovetoUnpacked( sqlite3_free(pCellKey); goto moveto_finish; } - c = xRecordCompare(nCell, pCellKey, pIdxKey, 0); + c = xRecordCompare(nCell, pCellKey, pIdxKey); sqlite3_free(pCellKey); } assert( diff --git a/src/vdbe.h b/src/vdbe.h index ef91010d80..f975f95543 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -212,10 +212,10 @@ void sqlite3VdbeSetVarmask(Vdbe*, int); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); -int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int); +int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **); -typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int); +typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); #ifndef SQLITE_OMIT_TRIGGER diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 65792b485e..5a0b330060 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3482,7 +3482,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ ** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the ** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). */ -int sqlite3VdbeRecordCompare( +static int vdbeRecordCompareWithSkip( int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2, /* Right key */ int bSkip /* If true, skip the first field */ @@ -3664,6 +3664,13 @@ int sqlite3VdbeRecordCompare( ); return pPKey2->default_rc; } +int sqlite3VdbeRecordCompare( + int nKey1, const void *pKey1, /* Left key */ + UnpackedRecord *pPKey2 /* Right key */ +){ + return vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); +} + /* ** This function is an optimized version of sqlite3VdbeRecordCompare() @@ -3676,8 +3683,7 @@ int sqlite3VdbeRecordCompare( */ static int vdbeRecordCompareInt( int nKey1, const void *pKey1, /* Left key */ - UnpackedRecord *pPKey2, /* Right key */ - int bSkip /* Ignored */ + UnpackedRecord *pPKey2 /* Right key */ ){ const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F]; int serial_type = ((const u8*)pKey1)[1]; @@ -3686,9 +3692,7 @@ static int vdbeRecordCompareInt( u64 x; i64 v = pPKey2->aMem[0].u.i; i64 lhs; - UNUSED_PARAMETER(bSkip); - assert( bSkip==0 ); assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB ); switch( serial_type ){ case 1: { /* 1-byte signed integer */ @@ -3738,10 +3742,10 @@ static int vdbeRecordCompareInt( ** (as gcc is clever enough to combine the two like cases). Other ** compilers might be similar. */ case 0: case 7: - return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0); + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); default: - return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0); + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); } if( v>lhs ){ @@ -3751,7 +3755,7 @@ static int vdbeRecordCompareInt( }else if( pPKey2->nField>1 ){ /* The first fields of the two keys are equal. Compare the trailing ** fields. */ - res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1); + res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ /* The first fields of the two keys are equal and there are no trailing ** fields. Return pPKey2->default_rc in this case. */ @@ -3770,17 +3774,13 @@ static int vdbeRecordCompareInt( */ static int vdbeRecordCompareString( int nKey1, const void *pKey1, /* Left key */ - UnpackedRecord *pPKey2, /* Right key */ - int bSkip + UnpackedRecord *pPKey2 /* Right key */ ){ const u8 *aKey1 = (const u8*)pKey1; int serial_type; int res; - UNUSED_PARAMETER(bSkip); - assert( bSkip==0 ); getVarint32(&aKey1[1], serial_type); - if( serial_type<12 ){ res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ }else if( !(serial_type & 0x01) ){ @@ -3802,7 +3802,7 @@ static int vdbeRecordCompareString( res = nStr - pPKey2->aMem[0].n; if( res==0 ){ if( pPKey2->nField>1 ){ - res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1); + res = vdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ res = pPKey2->default_rc; } @@ -3980,7 +3980,7 @@ int sqlite3VdbeIdxKeyCompare( if( rc ){ return rc; } - *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked, 0); + *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); sqlite3VdbeMemRelease(&m); return SQLITE_OK; } diff --git a/src/vdbesort.c b/src/vdbesort.c index b9a62bf569..2d7bc8a7a4 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -761,7 +761,7 @@ static int vdbeSorterCompare( if( pKey2 ){ sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); } - return sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0); + return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); } /* @@ -2517,6 +2517,6 @@ int sqlite3VdbeSorterCompare( } } - *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2, 0); + *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); return SQLITE_OK; } diff --git a/src/where.c b/src/where.c index 5b990fc108..c7cb7bb67c 100644 --- a/src/where.c +++ b/src/where.c @@ -1913,7 +1913,7 @@ static void whereKeyStats( assert( pRec->nField>0 && iColnSampleCol ); do{ iTest = (iMin+i)/2; - res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec, 0); + res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec); if( res<0 ){ iMin = iTest+1; }else{ @@ -1928,16 +1928,16 @@ static void whereKeyStats( if( res==0 ){ /* If (res==0) is true, then sample $i must be equal to pRec */ assert( inSample ); - assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0) + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) || pParse->db->mallocFailed ); }else{ /* Otherwise, pRec must be smaller than sample $i and larger than ** sample ($i-1). */ assert( i==pIdx->nSample - || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)>0 + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 || pParse->db->mallocFailed ); assert( i==0 - || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec, 0)<0 + || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 || pParse->db->mallocFailed ); } #endif /* ifdef SQLITE_DEBUG */ From 897a2d50f222721bc71c9835705618dff1a7801a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 14:55:08 +0000 Subject: [PATCH 30/65] Remove an unused parameter from sqlite3VdbeIdxRowid(). This is cosmetic only as the C-compiler optimizers were already omitting this parameter on amalgamation builds. FossilOrigin-Name: a10a6bba4963761b490b7243b388dcc920c4cfed --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 2 +- src/vdbeaux.c | 4 +--- 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 154cd1a029..8c762d224f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\snumber\sof\sarguments\sto\sRecordCompare\sfunctions\sfrom\s4\sto\s3,\nresulting\sin\sa\ssmall\sperformance\sincrease. -D 2014-09-16T14:37:35.076 +C Remove\san\sunused\sparameter\sfrom\ssqlite3VdbeIdxRowid().\s\sThis\sis\scosmetic\nonly\sas\sthe\sC-compiler\soptimizers\swere\salready\somitting\sthis\sparameter\son\namalgamation\sbuilds. +D 2014-09-16T14:55:08.312 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,11 +288,11 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359 F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 9a45dcbcc967fc0cb9248c75ba245d1d47de3e78 +F src/vdbe.c ae07ee84667c190d31946ae31c2fc63a3aa81a32 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h 0de8705e38b5f28808e37cebb9ec6df995ac3304 +F src/vdbeInt.h dc1743de339f5556cc6687219cf8727ad0d35f72 F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 -F src/vdbeaux.c d06769a7c1f8db9c04fe1457d357203a06684662 +F src/vdbeaux.c 79ce140ee79ecc7638eac070b48f1d24bbf9653c F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c 4d1e1398be24f85805196c20a80699be0699a9ca F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde @@ -1198,7 +1198,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 0be3019ed794c10de67dfd645ceea7d45815bc4b -R 4ac54fa45280398cdbf86b6ba8db7793 +P 8239c35aedd583af79505378bb7dbb78346a3f45 +R 8e31ee1c1cfa56f2cb381e2e177d1a9b U drh -Z fba86109c421937fd36d2c7c73cc5fa1 +Z 717af3cbede201cebaf3af532573dee2 diff --git a/manifest.uuid b/manifest.uuid index d03654a7d8..1d2c86f0a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8239c35aedd583af79505378bb7dbb78346a3f45 \ No newline at end of file +a10a6bba4963761b490b7243b388dcc920c4cfed \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index cc9e317e4b..b1764a12f4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4769,7 +4769,7 @@ case OP_IdxRowid: { /* out2-prerelease */ assert( pC->isTable==0 ); if( !pC->nullRow ){ rowid = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); + rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 5379d6b667..14ae09130c 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -398,7 +398,7 @@ void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); -int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); +int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeHalt(Vdbe*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 5a0b330060..b7e3da7584 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3876,7 +3876,7 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ ** pCur might be pointing to text obtained from a corrupt database file. ** So the content cannot be trusted. Do appropriate checks on the content. */ -int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ +int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ i64 nCellKey = 0; int rc; u32 szHdr; /* Size of the header */ @@ -3884,8 +3884,6 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ u32 lenRowid; /* Size of the rowid */ Mem m, v; - UNUSED_PARAMETER(db); - /* Get the size of the index entry. Only indices entries of less ** than 2GiB are support - anything large must be database corruption. ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so From 2a2a696cd754b117dc6b9dfa8e9bcdc46d9f1d72 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 18:22:44 +0000 Subject: [PATCH 31/65] Simplification of the OP_Column logic for the case of rows with overflow. FossilOrigin-Name: f73678038d8fc399c1ca55230ae45962007c909c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 38 ++++++++++++-------------------------- src/vdbemem.c | 7 +++++-- 4 files changed, 25 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 8c762d224f..100a334778 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\sparameter\sfrom\ssqlite3VdbeIdxRowid().\s\sThis\sis\scosmetic\nonly\sas\sthe\sC-compiler\soptimizers\swere\salready\somitting\sthis\sparameter\son\namalgamation\sbuilds. -D 2014-09-16T14:55:08.312 +C Simplification\sof\sthe\sOP_Column\slogic\sfor\sthe\scase\sof\srows\swith\soverflow. +D 2014-09-16T18:22:44.852 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,13 +288,13 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359 F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c ae07ee84667c190d31946ae31c2fc63a3aa81a32 +F src/vdbe.c ff1b0b4f41355ba207bdc691b1017e7642f42c6b F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h dc1743de339f5556cc6687219cf8727ad0d35f72 F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 F src/vdbeaux.c 79ce140ee79ecc7638eac070b48f1d24bbf9653c F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 4d1e1398be24f85805196c20a80699be0699a9ca +F src/vdbemem.c 8abc122ce5359a120196e0825dca9a08a787aff6 F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 8239c35aedd583af79505378bb7dbb78346a3f45 -R 8e31ee1c1cfa56f2cb381e2e177d1a9b +P a10a6bba4963761b490b7243b388dcc920c4cfed +R e7cf963c2745f47a3657ad38e9817c1f U drh -Z 717af3cbede201cebaf3af532573dee2 +Z 153a841014a3e255f6703a490d77aa20 diff --git a/manifest.uuid b/manifest.uuid index 1d2c86f0a0..9162c28d1d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a10a6bba4963761b490b7243b388dcc920c4cfed \ No newline at end of file +f73678038d8fc399c1ca55230ae45962007c909c \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index b1764a12f4..20301edc56 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2449,37 +2449,23 @@ case OP_Column: { && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) || (len = sqlite3VdbeSerialTypeLen(t))==0 ){ - /* Content is irrelevant for the typeof() function and for - ** the length(X) function if X is a blob. So we might as well use - ** bogus content rather than reading content from disk. NULL works - ** for text and blob and whatever is in the payloadSize64 variable - ** will work for everything else. Content is also irrelevant if - ** the content length is 0. */ - zData = t<=13 ? (u8*)&payloadSize64 : 0; - sMem.zMalloc = 0; + /* Content is irrelevant for + ** 1. the typeof() function, + ** 2. the length(X) function if X is a blob, and + ** 3. if the content length is zero. + ** So we might as well use bogus content rather than reading + ** content from disk. NULL will work for the value for strings + ** and blobs and whatever is in the payloadSize64 variable + ** will work for everything else. */ + sqlite3VdbeSerialGet(t<=13 ? (u8*)&payloadSize64 : 0, t, pDest); }else{ - memset(&sMem, 0, sizeof(sMem)); - sqlite3VdbeMemMove(&sMem, pDest); rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable, - &sMem); + pDest); if( rc!=SQLITE_OK ){ goto op_column_error; } - zData = (u8*)sMem.z; - } - sqlite3VdbeSerialGet(zData, t, pDest); - /* If we dynamically allocated space to hold the data (in the - ** sqlite3VdbeMemFromBtree() call above) then transfer control of that - ** dynamically allocated space over to the pDest structure. - ** This prevents a memory copy. */ - if( sMem.zMalloc ){ - assert( sMem.z==sMem.zMalloc ); - assert( VdbeMemDynamic(pDest)==0 ); - assert( (pDest->flags & (MEM_Blob|MEM_Str))==0 || pDest->z==sMem.z ); - pDest->flags &= ~(MEM_Ephem|MEM_Static); - pDest->flags |= MEM_Term; - pDest->z = sMem.z; - pDest->zMalloc = sMem.zMalloc; + sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); + pDest->flags &= ~MEM_Ephem; } } pDest->enc = encoding; diff --git a/src/vdbemem.c b/src/vdbemem.c index 7785bc0de5..432cd4e898 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -885,8 +885,11 @@ int sqlite3VdbeMemSetStr( ** key is true to get the key or false to get data. The result is written ** into the pMem element. ** -** The pMem structure is assumed to be uninitialized. Any prior content -** is overwritten without being freed. +** The pMem object must have been initialized. This routine will use +** pMem->zMalloc to hold the content from the btree, if possible. New +** pMem->zMalloc space will be allocated if necessary. The calling routine +** is responsible for making sure that the pMem object is eventually +** destroyed. ** ** If this routine fails for any reason (malloc returns NULL or unable ** to read from the disk) then the pMem is left in an inconsistent state. From 8740a600162808c84040356282fa2f5af95588ff Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 20:05:21 +0000 Subject: [PATCH 32/65] Make sure registers are cleared properly prior to being used to store the result of an OP_Column operator. FossilOrigin-Name: 78fb8838d80b229418c347c63579989432e1af7d --- manifest | 16 +++++++-------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeaux.c | 1 + src/vdbemem.c | 56 ++++++++++++++++++++++++++++++--------------------- 5 files changed, 44 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 100a334778..20bc2b4129 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sof\sthe\sOP_Column\slogic\sfor\sthe\scase\sof\srows\swith\soverflow. -D 2014-09-16T18:22:44.852 +C Make\ssure\sregisters\sare\scleared\sproperly\sprior\sto\sbeing\sused\sto\sstore\nthe\sresult\sof\san\sOP_Column\soperator. +D 2014-09-16T20:05:21.909 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,13 +288,13 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359 F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c ff1b0b4f41355ba207bdc691b1017e7642f42c6b +F src/vdbe.c 6a45baf86fcc6c294d57e0aef8c9f2c54f07ff18 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h dc1743de339f5556cc6687219cf8727ad0d35f72 F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 -F src/vdbeaux.c 79ce140ee79ecc7638eac070b48f1d24bbf9653c +F src/vdbeaux.c 211ad29d51e01c44a0db1ab69b74c11c8de1cccf F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 8abc122ce5359a120196e0825dca9a08a787aff6 +F src/vdbemem.c 18556fc614426886e380def839bdcf9cadbb752a F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 a10a6bba4963761b490b7243b388dcc920c4cfed -R e7cf963c2745f47a3657ad38e9817c1f +P f73678038d8fc399c1ca55230ae45962007c909c +R 39f3c2bf48f680cf4e99aef8c3698c28 U drh -Z 153a841014a3e255f6703a490d77aa20 +Z e586af33404759487ed3f6653fe697fa diff --git a/manifest.uuid b/manifest.uuid index 9162c28d1d..0d00de3592 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f73678038d8fc399c1ca55230ae45962007c909c \ No newline at end of file +78fb8838d80b229418c347c63579989432e1af7d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 20301edc56..4bdfbfbdeb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2437,10 +2437,10 @@ case OP_Column: { assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); assert( sqlite3VdbeCheckMemInvariants(pDest) ); + VdbeMemReleaseExtern(pDest); if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original ** page - where the content is not on an overflow page */ - VdbeMemReleaseExtern(pDest); sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); }else{ /* This branch happens only when content is on overflow pages */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index b7e3da7584..10495e76e4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3306,6 +3306,7 @@ static int vdbeCompareMemString( c1.db = c2.db = pMem1->db; c1.flags = c2.flags = 0; c1.zMalloc = c2.zMalloc = 0; + c1.xDel = c2.xDel = 0; sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); diff --git a/src/vdbemem.c b/src/vdbemem.c index 432cd4e898..c75046ab87 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -310,9 +310,13 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ } /* -** If the memory cell contains a string value that must be freed by -** invoking an external callback, free it now. Calling this function -** does not free any Mem.zMalloc buffer. +** If the memory cell contains a value that must be freed by +** invoking an external callback, then free it now. +** +** This routine does NOT do any of the following: +** (1) Set the Mem.flags field to a rational value. +** (2) Free memory held by Mem.zMalloc +** The caller is expected to take care of setting Mem.flags appropriately. ** ** The VdbeMemReleaseExtern() macro invokes this routine if only if there ** is work for this routine to do. @@ -340,8 +344,8 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ ** by p->xDel and memory in p->zMalloc. ** ** This is a helper routine invoked by sqlite3VdbeMemRelease() in -** the uncommon case when there really is memory in p that is -** need of freeing. +** the uncommon case when there really is memory in p that needs +** to be freeing. */ static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){ if( VdbeMemDynamic(p) ){ @@ -355,9 +359,11 @@ static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){ } /* -** Release any memory held by the Mem. This may leave the Mem in an -** inconsistent state, for example with (Mem.z==0) and -** (Mem.flags==MEM_Str). +** Release any memory held by the Mem. This may leave the Mem.flags in an +** inconsistent state, for example with (Mem.z==0) and (Mem.flags==MEM_Str). +** +** This routine releases both the Mem.xDel space and the Mem.zMalloc space. +** Use sqlite3VdbeMemReleaseExternal() to release just the Mem.xDel space. */ void sqlite3VdbeMemRelease(Mem *p){ assert( sqlite3VdbeCheckMemInvariants(p) ); @@ -733,7 +739,7 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( pTo->db==pFrom->db ); VdbeMemReleaseExtern(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); - pTo->xDel = 0; + assert( pTo->xDel==0 ); if( (pFrom->flags&MEM_Static)==0 ){ pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); assert( srcType==MEM_Ephem || srcType==MEM_Static ); @@ -753,7 +759,7 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ VdbeMemReleaseExtern(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; - pTo->xDel = 0; + assert( pTo->xDel==0 ); if( pTo->flags&(MEM_Str|MEM_Blob) ){ if( 0==(pFrom->flags&MEM_Static) ){ @@ -906,6 +912,7 @@ int sqlite3VdbeMemFromBtree( int rc = SQLITE_OK; /* Return code */ assert( sqlite3BtreeCursorIsValid(pCur) ); + assert( pMem->xDel==0 ); /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ @@ -922,19 +929,22 @@ int sqlite3VdbeMemFromBtree( pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; pMem->n = (int)amt; - }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){ - if( key ){ - rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); - }else{ - rc = sqlite3BtreeData(pCur, offset, amt, pMem->z); - } - if( rc==SQLITE_OK ){ - pMem->z[amt] = 0; - pMem->z[amt+1] = 0; - pMem->flags = MEM_Blob|MEM_Term; - pMem->n = (int)amt; - }else{ - sqlite3VdbeMemRelease(pMem); + }else{ + pMem->flags = MEM_Null; + if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){ + if( key ){ + rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); + }else{ + rc = sqlite3BtreeData(pCur, offset, amt, pMem->z); + } + if( rc==SQLITE_OK ){ + pMem->z[amt] = 0; + pMem->z[amt+1] = 0; + pMem->flags = MEM_Blob|MEM_Term; + pMem->n = (int)amt; + }else{ + sqlite3VdbeMemRelease(pMem); + } } } From 6b478bcd9ec466846dba80446636a2cbd992b221 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Sep 2014 21:54:11 +0000 Subject: [PATCH 33/65] Continuing cleanup of memory register memory allocation handling. FossilOrigin-Name: 2598aedc5dd2bac67e2e518a31f2803e469c2ba6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/utf.c | 4 ++-- src/vdbemem.c | 17 ++++++++--------- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 20bc2b4129..0c48965589 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sregisters\sare\scleared\sproperly\sprior\sto\sbeing\sused\sto\sstore\nthe\sresult\sof\san\sOP_Column\soperator. -D 2014-09-16T20:05:21.909 +C Continuing\scleanup\sof\smemory\sregister\smemory\sallocation\shandling. +D 2014-09-16T21:54:11.409 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -285,7 +285,7 @@ F src/threads.c 22dded4283dc4b25422f6444cdcb8d6b1ea0b5ff F src/tokenize.c 3df63041994f55afeb168b463ec836e8f1c50e7c F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 -F src/utf.c 77abb5e6d27f3d236e50f7c8fff1d00e15262359 +F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 6a45baf86fcc6c294d57e0aef8c9f2c54f07ff18 @@ -294,7 +294,7 @@ F src/vdbeInt.h dc1743de339f5556cc6687219cf8727ad0d35f72 F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 F src/vdbeaux.c 211ad29d51e01c44a0db1ab69b74c11c8de1cccf F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 18556fc614426886e380def839bdcf9cadbb752a +F src/vdbemem.c 9615c9aba37ec42bd6ea705d3d72379c77720b00 F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 f73678038d8fc399c1ca55230ae45962007c909c -R 39f3c2bf48f680cf4e99aef8c3698c28 +P 78fb8838d80b229418c347c63579989432e1af7d +R 386107f24552e12c4df7dfd8a184a53a U drh -Z e586af33404759487ed3f6653fe697fa +Z 90927a6d3c50834bddf5d6b0b977d8d6 diff --git a/manifest.uuid b/manifest.uuid index 0d00de3592..1ed225fb04 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -78fb8838d80b229418c347c63579989432e1af7d \ No newline at end of file +2598aedc5dd2bac67e2e518a31f2803e469c2ba6 \ No newline at end of file diff --git a/src/utf.c b/src/utf.c index 557f3a95e4..549983f6f1 100644 --- a/src/utf.c +++ b/src/utf.c @@ -314,10 +314,10 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ *z = 0; assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); + c = pMem->flags; sqlite3VdbeMemRelease(pMem); - pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem); + pMem->flags = MEM_Str|MEM_Term|(c&MEM_AffMask); pMem->enc = desiredEnc; - pMem->flags |= (MEM_Term); pMem->z = (char*)zOut; pMem->zMalloc = pMem->z; diff --git a/src/vdbemem.c b/src/vdbemem.c index c75046ab87..27a2301a9d 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -335,8 +335,11 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ }else if( p->flags&MEM_RowSet ){ sqlite3RowSetClear(p->u.pRowSet); }else if( p->flags&MEM_Frame ){ - sqlite3VdbeMemSetNull(p); + VdbeFrame *pFrame = p->u.pFrame; + pFrame->pParent = pFrame->v->pDelFrame; + pFrame->v->pDelFrame = pFrame; } + p->flags = MEM_Null; } /* @@ -589,15 +592,11 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ ** Delete any previous value and set the value stored in *pMem to NULL. */ void sqlite3VdbeMemSetNull(Mem *pMem){ - if( pMem->flags & MEM_Frame ){ - VdbeFrame *pFrame = pMem->u.pFrame; - pFrame->pParent = pFrame->v->pDelFrame; - pFrame->v->pDelFrame = pFrame; + if( VdbeMemDynamic(pMem) ){ + sqlite3VdbeMemReleaseExternal(pMem); + }else{ + pMem->flags = MEM_Null; } - if( pMem->flags & MEM_RowSet ){ - sqlite3RowSetClear(pMem->u.pRowSet); - } - MemSetTypeFlag(pMem, MEM_Null); } void sqlite3ValueSetNull(sqlite3_value *p){ sqlite3VdbeMemSetNull((Mem*)p); From 0725cabe3a807b1fe8065ef3689dcfb8b4242265 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Sep 2014 14:52:46 +0000 Subject: [PATCH 34/65] Improved interface to the Mem object handling. Small size reduction and performance increase. FossilOrigin-Name: 4e437844322cc20eef92928b53fa6b37eded586e --- manifest | 18 +++++------ manifest.uuid | 2 +- src/vdbe.c | 22 +++++++------- src/vdbeInt.h | 3 -- src/vdbeapi.c | 3 +- src/vdbemem.c | 83 +++++++++++++++++++++++++-------------------------- 6 files changed, 63 insertions(+), 68 deletions(-) diff --git a/manifest b/manifest index 0c48965589..56db1ec750 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Continuing\scleanup\sof\smemory\sregister\smemory\sallocation\shandling. -D 2014-09-16T21:54:11.409 +C Improved\sinterface\sto\sthe\sMem\sobject\shandling.\s\sSmall\ssize\sreduction\sand\nperformance\sincrease. +D 2014-09-17T14:52:46.727 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,13 +288,13 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 6a45baf86fcc6c294d57e0aef8c9f2c54f07ff18 +F src/vdbe.c d39487782c0c6a2448bd1b351eba6a2dce101343 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h dc1743de339f5556cc6687219cf8727ad0d35f72 -F src/vdbeapi.c 4d2aa56efa1b4a010012466bf8e97dbf179081a6 +F src/vdbeInt.h 9d398055c873980b61ce0f7bf82140a8e4e2ccbc +F src/vdbeapi.c c6e63f913bcb12977731a8b12e7e5c5762981527 F src/vdbeaux.c 211ad29d51e01c44a0db1ab69b74c11c8de1cccf F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 9615c9aba37ec42bd6ea705d3d72379c77720b00 +F src/vdbemem.c cf552a404f0e73a48bd266699aa27f0df26b096b F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 78fb8838d80b229418c347c63579989432e1af7d -R 386107f24552e12c4df7dfd8a184a53a +P 2598aedc5dd2bac67e2e518a31f2803e469c2ba6 +R f63e98cc1bcae44946c79c20cdee7610 U drh -Z 90927a6d3c50834bddf5d6b0b977d8d6 +Z 1559702e8c6b5218f324b4f43d7dc2c7 diff --git a/manifest.uuid b/manifest.uuid index 1ed225fb04..52a893ba83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2598aedc5dd2bac67e2e518a31f2803e469c2ba6 \ No newline at end of file +4e437844322cc20eef92928b53fa6b37eded586e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 4bdfbfbdeb..edccc1c601 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -640,7 +640,7 @@ int sqlite3VdbeExec( assert( pOp->p2<=(p->nMem-p->nCursor) ); pOut = &aMem[pOp->p2]; memAboutToChange(p, pOut); - VdbeMemReleaseExtern(pOut); + if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); pOut->flags = MEM_Int; } @@ -1079,7 +1079,7 @@ case OP_Null: { /* out2-prerelease */ while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); - VdbeMemReleaseExtern(pOut); + sqlite3VdbeMemSetNull(pOut); pOut->flags = nullFlag; cnt--; } @@ -2107,10 +2107,10 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ case OP_Not: { /* same as TK_NOT, in1, out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; - if( pIn1->flags & MEM_Null ){ - sqlite3VdbeMemSetNull(pOut); - }else{ - sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1)); + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = !sqlite3VdbeIntValue(pIn1); } break; } @@ -2125,10 +2125,10 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; - if( pIn1->flags & MEM_Null ){ - sqlite3VdbeMemSetNull(pOut); - }else{ - sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1)); + sqlite3VdbeMemSetNull(pOut); + if( (pIn1->flags & MEM_Null)==0 ){ + pOut->flags = MEM_Int; + pOut->u.i = ~sqlite3VdbeIntValue(pIn1); } break; } @@ -2437,7 +2437,7 @@ case OP_Column: { assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); assert( sqlite3VdbeCheckMemInvariants(pDest) ); - VdbeMemReleaseExtern(pDest); + if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest); if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original ** page - where the content is not on an overflow page */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 14ae09130c..556dfa16c7 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -429,11 +429,8 @@ int sqlite3VdbeMemNumerify(Mem*); void sqlite3VdbeMemCast(Mem*,u8,u8); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); -void sqlite3VdbeMemReleaseExternal(Mem *p); #define VdbeMemDynamic(X) \ (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) -#define VdbeMemReleaseExtern(X) \ - if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 14d6b8412e..dbfabebbf0 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -662,8 +662,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ Mem *pMem = p->pMem; assert( (pMem->flags & MEM_Agg)==0 ); if( nByte<=0 ){ - sqlite3VdbeMemReleaseExternal(pMem); - pMem->flags = MEM_Null; + sqlite3VdbeMemSetNull(pMem); pMem->z = 0; }else{ sqlite3VdbeMemGrow(pMem, nByte, 0); diff --git a/src/vdbemem.c b/src/vdbemem.c index 27a2301a9d..e1b4e4949f 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -48,7 +48,6 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1 ); } - return 1; } #endif @@ -121,9 +120,8 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); } if( pMem->zMalloc==0 ){ - VdbeMemReleaseExtern(pMem); + sqlite3VdbeMemSetNull(pMem); pMem->z = 0; - pMem->flags = MEM_Null; return SQLITE_NOMEM; } } @@ -311,23 +309,22 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ /* ** If the memory cell contains a value that must be freed by -** invoking an external callback, then free it now. +** invoking the external callback in Mem.xDel, then this routine +** will free that value. It also sets Mem.flags to MEM_Null. ** -** This routine does NOT do any of the following: -** (1) Set the Mem.flags field to a rational value. -** (2) Free memory held by Mem.zMalloc -** The caller is expected to take care of setting Mem.flags appropriately. -** -** The VdbeMemReleaseExtern() macro invokes this routine if only if there -** is work for this routine to do. +** This is a helper routine for sqlite3VdbeMemSetNull() and +** for sqlite3VdbeMemRelease(). Use those other routines as the +** entry point for releasing Mem resources. */ -void sqlite3VdbeMemReleaseExternal(Mem *p){ +static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); + assert( VdbeMemDynamic(p) ); if( p->flags&MEM_Agg ){ sqlite3VdbeMemFinalize(p, p->u.pDef); assert( (p->flags & MEM_Agg)==0 ); - sqlite3VdbeMemRelease(p); - }else if( p->flags&MEM_Dyn ){ + testcase( p->flags & MEM_Dyn ); + } + if( p->flags&MEM_Dyn ){ assert( (p->flags&MEM_RowSet)==0 ); assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); p->xDel((void *)p->z); @@ -347,12 +344,12 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){ ** by p->xDel and memory in p->zMalloc. ** ** This is a helper routine invoked by sqlite3VdbeMemRelease() in -** the uncommon case when there really is memory in p that needs -** to be freeing. +** the unusual case where there really is memory in p that needs +** to be freed. */ -static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){ +static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ if( VdbeMemDynamic(p) ){ - sqlite3VdbeMemReleaseExternal(p); + vdbeMemClearExternAndSetNull(p); } if( p->zMalloc ){ sqlite3DbFree(p->db, p->zMalloc); @@ -362,18 +359,19 @@ static SQLITE_NOINLINE void vdbeMemRelease(Mem *p){ } /* -** Release any memory held by the Mem. This may leave the Mem.flags in an -** inconsistent state, for example with (Mem.z==0) and (Mem.flags==MEM_Str). +** Release any memory resources held by the Mem. Both the memory that is +** free by Mem.xDel and the Mem.zMalloc allocation are freed. ** -** This routine releases both the Mem.xDel space and the Mem.zMalloc space. -** Use sqlite3VdbeMemReleaseExternal() to release just the Mem.xDel space. +** Use this routine prior to clean up prior to abandoning a Mem, or to +** reset a Mem back to its minimum memory utilization. +** +** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space +** prior to inserting new content into the Mem. */ void sqlite3VdbeMemRelease(Mem *p){ assert( sqlite3VdbeCheckMemInvariants(p) ); if( VdbeMemDynamic(p) || p->zMalloc ){ - vdbeMemRelease(p); - }else{ - p->z = 0; + vdbeMemClear(p); } assert( p->xDel==0 ); } @@ -590,10 +588,19 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ /* ** Delete any previous value and set the value stored in *pMem to NULL. +** +** This routine calls the Mem.xDel destructor to dispose of values that +** require the destructor. But it preserves the Mem.zMalloc memory allocation. +** To free all resources, use sqlite3VdbeMemRelease(), which both calls this +** routine to invoke the destructor and deallocates Mem.zMalloc. +** +** Use this routine to reset the Mem prior to insert a new value. +** +** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. */ void sqlite3VdbeMemSetNull(Mem *pMem){ if( VdbeMemDynamic(pMem) ){ - sqlite3VdbeMemReleaseExternal(pMem); + vdbeMemClearExternAndSetNull(pMem); }else{ pMem->flags = MEM_Null; } @@ -613,14 +620,7 @@ void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ if( n<0 ) n = 0; pMem->u.nZero = n; pMem->enc = SQLITE_UTF8; - -#ifdef SQLITE_OMIT_INCRBLOB - sqlite3VdbeMemGrow(pMem, n, 0); - if( pMem->z ){ - pMem->n = n; - memset(pMem->z, 0, n); - } -#endif + pMem->z = 0; } /* @@ -629,7 +629,7 @@ void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ ** a 64-bit integer. */ static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ - sqlite3VdbeMemReleaseExternal(pMem); + sqlite3VdbeMemSetNull(pMem); pMem->u.i = val; pMem->flags = MEM_Int; } @@ -653,10 +653,8 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ ** manifest type REAL. */ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ - if( sqlite3IsNaN(val) ){ - sqlite3VdbeMemSetNull(pMem); - }else{ - sqlite3VdbeMemRelease(pMem); + sqlite3VdbeMemSetNull(pMem); + if( !sqlite3IsNaN(val) ){ pMem->r = val; pMem->flags = MEM_Real; } @@ -736,7 +734,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( (pFrom->flags & MEM_RowSet)==0 ); assert( pTo->db==pFrom->db ); - VdbeMemReleaseExtern(pTo); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); assert( pTo->xDel==0 ); if( (pFrom->flags&MEM_Static)==0 ){ @@ -755,7 +753,7 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ assert( pTo->db==pFrom->db ); assert( (pFrom->flags & MEM_RowSet)==0 ); - VdbeMemReleaseExtern(pTo); + if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; assert( pTo->xDel==0 ); @@ -832,7 +830,8 @@ int sqlite3VdbeMemSetStr( if( nByte<0 ){ assert( enc!=0 ); if( enc==SQLITE_UTF8 ){ - for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){} + nByte = sqlite3Strlen30(z); + if( nByte>iLimit ) nByte = iLimit+1; }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} } From d3b74200a871af8ac8e4b36a84eafe658aa0aa12 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Sep 2014 16:41:15 +0000 Subject: [PATCH 35/65] In the Mem object, stop requiring that Mem.xDel be NULL when the MEM_Dyn bit is clear. Also reduce the amount of initialization of Mem objects. All for a small size reduction and performance increase. FossilOrigin-Name: fdddb477c89dabb9f7bf2d5ccb32534868df3a03 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 12 +++--------- src/vdbeInt.h | 7 ++++--- src/vdbeaux.c | 9 ++++----- src/vdbemem.c | 30 ++++++++++++++++-------------- 6 files changed, 37 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index 56db1ec750..369f641908 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sinterface\sto\sthe\sMem\sobject\shandling.\s\sSmall\ssize\sreduction\sand\nperformance\sincrease. -D 2014-09-17T14:52:46.727 +C In\sthe\sMem\sobject,\sstop\srequiring\sthat\sMem.xDel\sbe\sNULL\swhen\sthe\sMEM_Dyn\nbit\sis\sclear.\s\sAlso\sreduce\sthe\samount\sof\sinitialization\sof\sMem\sobjects.\nAll\sfor\sa\ssmall\ssize\sreduction\sand\sperformance\sincrease. +D 2014-09-17T16:41:15.094 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,13 +288,13 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c d39487782c0c6a2448bd1b351eba6a2dce101343 +F src/vdbe.c d3c548ad4ea6a5549d2d0b502070e0523023ff97 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h 9d398055c873980b61ce0f7bf82140a8e4e2ccbc +F src/vdbeInt.h f90b0de6153f50de630a5a113537efb47083812f F src/vdbeapi.c c6e63f913bcb12977731a8b12e7e5c5762981527 -F src/vdbeaux.c 211ad29d51e01c44a0db1ab69b74c11c8de1cccf +F src/vdbeaux.c 9ac63bc59d2783df77e591e4c4fa8c1153a07eab F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c cf552a404f0e73a48bd266699aa27f0df26b096b +F src/vdbemem.c 8b5e1083fed2da94e315858a7edf5604a5b91804 F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 2598aedc5dd2bac67e2e518a31f2803e469c2ba6 -R f63e98cc1bcae44946c79c20cdee7610 +P 4e437844322cc20eef92928b53fa6b37eded586e +R 8244691fd19236cfb5e445e4012669fa U drh -Z 1559702e8c6b5218f324b4f43d7dc2c7 +Z ef23a1637c5e3046b6cead80453b022e diff --git a/manifest.uuid b/manifest.uuid index 52a893ba83..2cf0d22ed7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e437844322cc20eef92928b53fa6b37eded586e \ No newline at end of file +fdddb477c89dabb9f7bf2d5ccb32534868df3a03 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index edccc1c601..5ab14c5cbf 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1174,7 +1174,6 @@ case OP_Move: { } #endif pIn1->flags = MEM_Undefined; - pIn1->xDel = 0; pIn1->zMalloc = zMalloc; REGISTER_TRACE(p2++, pOut); pIn1++; @@ -2645,7 +2644,6 @@ case OP_MakeRecord: { assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pOut->n = (int)nByte; pOut->flags = MEM_Blob; - pOut->xDel = 0; if( nZero ){ pOut->u.nZero = nZero; pOut->flags |= MEM_Zero; @@ -4755,7 +4753,7 @@ case OP_IdxRowid: { /* out2-prerelease */ assert( pC->isTable==0 ); if( !pC->nullRow ){ rowid = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); + rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -4839,7 +4837,7 @@ case OP_IdxGE: { /* jump */ { int i; for(i=0; iopcode&1)==(OP_IdxLT&1) ){ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); @@ -5609,11 +5607,7 @@ case OP_AggStep: { assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); ctx.pMem = pMem = &aMem[pOp->p3]; pMem->n++; - t.flags = MEM_Null; - t.z = 0; - t.zMalloc = 0; - t.xDel = 0; - t.db = db; + sqlite3VdbeMemInit(&t, db, MEM_Null); ctx.pOut = &t; ctx.isError = 0; ctx.pColl = 0; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 556dfa16c7..9c7378a26c 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -176,7 +176,7 @@ struct Mem { char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ /* ShallowCopy only needs to copy the information above */ sqlite3 *db; /* The associated database connection */ - void (*xDel)(void*);/* If not null, call this function to delete Mem.z */ + void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ @@ -397,8 +397,8 @@ u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); -int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); -int sqlite3VdbeIdxRowid(BtCursor *, i64 *); +int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); +int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeHalt(Vdbe*); @@ -415,6 +415,7 @@ void sqlite3VdbeMemSetInt64(Mem*, i64); #else void sqlite3VdbeMemSetDouble(Mem*, double); #endif +void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); void sqlite3VdbeMemSetNull(Mem*); void sqlite3VdbeMemSetZeroBlob(Mem*,int); void sqlite3VdbeMemSetRowSet(Mem*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 10495e76e4..8466bfb30a 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3085,7 +3085,6 @@ u32 sqlite3VdbeSerialGet( static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; pMem->z = (char *)buf; pMem->n = (serial_type-12)/2; - pMem->xDel = 0; pMem->flags = aFlag[serial_type&1]; return pMem->n; } @@ -3306,7 +3305,6 @@ static int vdbeCompareMemString( c1.db = c2.db = pMem1->db; c1.flags = c2.flags = 0; c1.zMalloc = c2.zMalloc = 0; - c1.xDel = c2.xDel = 0; sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); @@ -3877,7 +3875,7 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ ** pCur might be pointing to text obtained from a corrupt database file. ** So the content cannot be trusted. Do appropriate checks on the content. */ -int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ +int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ i64 nCellKey = 0; int rc; u32 szHdr; /* Size of the header */ @@ -3896,7 +3894,7 @@ int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); /* Read in the complete content of the index entry */ - memset(&m, 0, sizeof(m)); + sqlite3VdbeMemInit(&m, db, 0); rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); if( rc ){ return rc; @@ -3956,6 +3954,7 @@ idx_rowid_corruption: ** of the keys prior to the final rowid, not the entire key. */ int sqlite3VdbeIdxKeyCompare( + sqlite3 *db, /* Database connection */ VdbeCursor *pC, /* The cursor to compare against */ UnpackedRecord *pUnpacked, /* Unpacked version of key */ int *res /* Write the comparison result here */ @@ -3974,7 +3973,7 @@ int sqlite3VdbeIdxKeyCompare( *res = 0; return SQLITE_CORRUPT_BKPT; } - memset(&m, 0, sizeof(m)); + sqlite3VdbeMemInit(&m, db, 0); rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m); if( rc ){ return rc; diff --git a/src/vdbemem.c b/src/vdbemem.c index e1b4e4949f..359abb891f 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -26,11 +26,10 @@ ** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); */ int sqlite3VdbeCheckMemInvariants(Mem *p){ - /* The MEM_Dyn bit is set if and only if Mem.xDel is a non-NULL destructor - ** function for Mem.z + /* If MEM_Dyn is set then Mem.xDel!=0. + ** Mem.xDel is might not be initialized if MEM_Dyn is clear. */ assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); - assert( (p->flags & MEM_Dyn)!=0 || p->xDel==0 ); /* If p holds a string or blob, the Mem.z must point to exactly ** one of the following: @@ -136,7 +135,6 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ pMem->z = pMem->zMalloc; pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static); - pMem->xDel = 0; return SQLITE_OK; } @@ -299,7 +297,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ctx.pMem = pMem; ctx.pFunc = pFunc; pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ - assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel ); + assert( (pMem->flags & MEM_Dyn)==0 ); sqlite3DbFree(pMem->db, pMem->zMalloc); memcpy(pMem, &t, sizeof(t)); rc = ctx.isError; @@ -328,7 +326,6 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ assert( (p->flags&MEM_RowSet)==0 ); assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); p->xDel((void *)p->z); - p->xDel = 0; }else if( p->flags&MEM_RowSet ){ sqlite3RowSetClear(p->u.pRowSet); }else if( p->flags&MEM_Frame ){ @@ -373,7 +370,6 @@ void sqlite3VdbeMemRelease(Mem *p){ if( VdbeMemDynamic(p) || p->zMalloc ){ vdbeMemClear(p); } - assert( p->xDel==0 ); } /* @@ -585,6 +581,18 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ } } +/* +** Initialize bulk memory to be a consistent Mem object. +** +** The minimum amount of initialization feasible is performed. +*/ +void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){ + assert( (flags & ~MEM_TypeMask)==0 ); + pMem->flags = flags; + pMem->db = db; + pMem->zMalloc = 0; +} + /* ** Delete any previous value and set the value stored in *pMem to NULL. @@ -736,7 +744,6 @@ void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ assert( pTo->db==pFrom->db ); if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); - assert( pTo->xDel==0 ); if( (pFrom->flags&MEM_Static)==0 ){ pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem); assert( srcType==MEM_Ephem || srcType==MEM_Static ); @@ -756,8 +763,6 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; - assert( pTo->xDel==0 ); - if( pTo->flags&(MEM_Str|MEM_Blob) ){ if( 0==(pFrom->flags&MEM_Static) ){ pTo->flags |= MEM_Ephem; @@ -782,7 +787,6 @@ void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ sqlite3VdbeMemRelease(pTo); memcpy(pTo, pFrom, sizeof(Mem)); pFrom->flags = MEM_Null; - pFrom->xDel = 0; pFrom->zMalloc = 0; } @@ -857,7 +861,6 @@ int sqlite3VdbeMemSetStr( }else if( xDel==SQLITE_DYNAMIC ){ sqlite3VdbeMemRelease(pMem); pMem->zMalloc = pMem->z = (char *)z; - pMem->xDel = 0; }else{ sqlite3VdbeMemRelease(pMem); pMem->z = (char *)z; @@ -910,7 +913,7 @@ int sqlite3VdbeMemFromBtree( int rc = SQLITE_OK; /* Return code */ assert( sqlite3BtreeCursorIsValid(pCur) ); - assert( pMem->xDel==0 ); + assert( !VdbeMemDynamic(pMem) ); /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ @@ -923,7 +926,6 @@ int sqlite3VdbeMemFromBtree( assert( zData!=0 ); if( offset+amt<=available ){ - sqlite3VdbeMemRelease(pMem); pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; pMem->n = (int)amt; From ca5506bdc482bbfde2fe3dd6a93f079e9801ce60 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Sep 2014 23:37:38 +0000 Subject: [PATCH 36/65] Performance improvement and slight size reduction to the comparison operators in the VDBE. FossilOrigin-Name: 14052a7d088bed8196d90a3361ce717a5193bdc8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 14 ++++++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 369f641908..12094ebf72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sMem\sobject,\sstop\srequiring\sthat\sMem.xDel\sbe\sNULL\swhen\sthe\sMEM_Dyn\nbit\sis\sclear.\s\sAlso\sreduce\sthe\samount\sof\sinitialization\sof\sMem\sobjects.\nAll\sfor\sa\ssmall\ssize\sreduction\sand\sperformance\sincrease. -D 2014-09-17T16:41:15.094 +C Performance\simprovement\sand\sslight\ssize\sreduction\sto\sthe\scomparison\soperators\nin\sthe\sVDBE. +D 2014-09-17T23:37:39.000 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c d3c548ad4ea6a5549d2d0b502070e0523023ff97 +F src/vdbe.c 78606777e4ce5dba147ab75e71c0127b0d8d4c3d F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f90b0de6153f50de630a5a113537efb47083812f F src/vdbeapi.c c6e63f913bcb12977731a8b12e7e5c5762981527 @@ -1198,7 +1198,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 4e437844322cc20eef92928b53fa6b37eded586e -R 8244691fd19236cfb5e445e4012669fa +P fdddb477c89dabb9f7bf2d5ccb32534868df3a03 +R 27b98108123b0758f30cbbc4e2693ca1 U drh -Z ef23a1637c5e3046b6cead80453b022e +Z 7dd9c2f8b2084fea7b27f362515d2b5a diff --git a/manifest.uuid b/manifest.uuid index 2cf0d22ed7..2a5acf5d23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fdddb477c89dabb9f7bf2d5ccb32534868df3a03 \ No newline at end of file +14052a7d088bed8196d90a3361ce717a5193bdc8 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5ab14c5cbf..f964a73878 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1911,8 +1911,14 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ } assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); - ExpandBlob(pIn1); - ExpandBlob(pIn3); + if( pIn1->flags & MEM_Zero ){ + sqlite3VdbeMemExpandBlob(pIn1); + flags1 &= ~MEM_Zero; + } + if( pIn3->flags & MEM_Zero ){ + sqlite3VdbeMemExpandBlob(pIn3); + flags3 &= ~MEM_Zero; + } res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } switch( pOp->opcode ){ @@ -1937,8 +1943,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ } } /* Undo any changes made by applyAffinity() to the input registers. */ - pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask); - pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask); + pIn1->flags = flags1; + pIn3->flags = flags3; break; } From 3329a63ac5ca50861d926248b159106cd9fd96a5 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Sep 2014 01:21:43 +0000 Subject: [PATCH 37/65] Fix compiler warnings and change the nullMem structure initializer into a format that MSVC can understand. FossilOrigin-Name: 163bfae8583b2d3002a3a43d6bf8a66fefd73acb --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/malloc.c | 8 ++++---- src/table.c | 2 +- src/vdbeapi.c | 26 +++++++++++++------------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 12094ebf72..a6cdd2c40c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sand\sslight\ssize\sreduction\sto\sthe\scomparison\soperators\nin\sthe\sVDBE. -D 2014-09-17T23:37:39.000 +C Fix\scompiler\swarnings\sand\schange\sthe\snullMem\sstructure\sinitializer\sinto\sa\nformat\sthat\sMSVC\scan\sunderstand. +D 2014-09-18T01:21:43.977 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -194,7 +194,7 @@ F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994 F src/main.c d15621461fb0c52675eba2b650492ed1beef69ab -F src/malloc.c cc015821ba267ad5c91dc8761d0498a3fc3ce6ce +F src/malloc.c c6dc1e154eb7d4a33eb737bde2c4103d00007597 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f @@ -234,7 +234,7 @@ F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h 0803e900eb1882f7dd88e86ddcddd2d1b27c8d86 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 -F src/table.c 218ae2ba022881846741dfc8351aefdf129e0377 +F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb F src/tclsqlite.c c67d310c833046cccc192125d64ad422ab882684 F src/test1.c 523cd70ded28db71af9a30ec184cbe0957de9575 F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712 @@ -291,7 +291,7 @@ F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 78606777e4ce5dba147ab75e71c0127b0d8d4c3d F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f90b0de6153f50de630a5a113537efb47083812f -F src/vdbeapi.c c6e63f913bcb12977731a8b12e7e5c5762981527 +F src/vdbeapi.c c02242df5e9e8d1001e0086f405953833f9c426b F src/vdbeaux.c 9ac63bc59d2783df77e591e4c4fa8c1153a07eab F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c 8b5e1083fed2da94e315858a7edf5604a5b91804 @@ -1198,7 +1198,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 fdddb477c89dabb9f7bf2d5ccb32534868df3a03 -R 27b98108123b0758f30cbbc4e2693ca1 +P 14052a7d088bed8196d90a3361ce717a5193bdc8 +R fdb25cd80d01110b7b302f5203339ac7 U drh -Z 7dd9c2f8b2084fea7b27f362515d2b5a +Z 3225a18fbab1063469f56e7e3c1f239a diff --git a/manifest.uuid b/manifest.uuid index 2a5acf5d23..6cec555758 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14052a7d088bed8196d90a3361ce717a5193bdc8 \ No newline at end of file +163bfae8583b2d3002a3a43d6bf8a66fefd73acb \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index daf646bc30..a4acd2f0ce 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -305,7 +305,7 @@ void *sqlite3Malloc(u64 n){ p = 0; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); - mallocWithAlarm(n, &p); + mallocWithAlarm((int)n, &p); sqlite3_mutex_leave(mem0.mutex); }else{ p = sqlite3GlobalConfig.m.xMalloc((int)n); @@ -549,7 +549,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){ pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); + sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); nDiff = nNew - nOld; if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= mem0.alarmThreshold-nDiff ){ @@ -559,7 +559,7 @@ void *sqlite3Realloc(void *pOld, u64 nBytes){ assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmCallback ){ - sqlite3MallocAlarm(nBytes); + sqlite3MallocAlarm((int)nBytes); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } if( pNew ){ @@ -699,7 +699,7 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - pNew = sqlite3_realloc(p, n); + pNew = sqlite3_realloc64(p, n); if( !pNew ){ sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP); db->mallocFailed = 1; diff --git a/src/table.c b/src/table.c index 12d0cf548e..c435b2bc02 100644 --- a/src/table.c +++ b/src/table.c @@ -73,7 +73,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ if( z==0 ) goto malloc_failed; p->azResult[p->nData++] = z; } - }else if( p->nColumn!=nCol ){ + }else if( (int)p->nColumn!=nCol ){ sqlite3_free(p->zErrMsg); p->zErrMsg = sqlite3_mprintf( "sqlite3_get_table() called with two or more incompatible queries" diff --git a/src/vdbeapi.c b/src/vdbeapi.c index dbfabebbf0..ef1167a52d 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -803,18 +803,18 @@ static const Mem *columnNullValue(void){ __attribute__((aligned(8))) #endif = { - .flags = MEM_Null, - .enc = 0, - .n = 0, - .r = (double)0, - .u = {0}, - .z = 0, - .zMalloc = 0, - .db = 0, - .xDel = 0, + /* .u = */ {0}, + /* .flags = */ MEM_Null, + /* .enc = */ 0, + /* .n = */ 0, + /* .r = */ (double)0, + /* .z = */ 0, + /* .zMalloc = */ 0, + /* .db = */ 0, + /* .xDel = */ 0, #ifdef SQLITE_DEBUG - .pScopyFrom = 0, - .pFiller = 0, + /* .pScopyFrom = */ 0, + /* .pFiller = */ 0, #endif }; return &nullMem; @@ -1193,7 +1193,7 @@ int sqlite3_bind_blob64( if( nData>0x7fffffff ){ return invokeValueDestructor(zData, xDel, 0); }else{ - return bindText(pStmt, i, zData, nData, xDel, 0); + return bindText(pStmt, i, zData, (int)nData, xDel, 0); } } int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ @@ -1250,7 +1250,7 @@ int sqlite3_bind_text64( return invokeValueDestructor(zData, xDel, 0); }else{ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - return bindText(pStmt, i, zData, nData, xDel, enc); + return bindText(pStmt, i, zData, (int)nData, xDel, enc); } } #ifndef SQLITE_OMIT_UTF16 From 760b15984bc16e1e90eb89bc79daa25ba7dd9f40 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Sep 2014 01:50:09 +0000 Subject: [PATCH 38/65] Make sure of the strchrnul() library function on platforms where it is available. FossilOrigin-Name: ef1aa10b7f54912cba71cd0a98c5055d501de54f --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/printf.c | 23 +++++++++++++++++++++-- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d8b46a196d..f1b8ecd79c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\smicro-optimizations\sinto\strunk\safter\sfixing\sthe\sbuild\son\sMSVC.\nPerformance\snow\sshows\s7.58%\sfaster\sthan\sthe\s3.8.6\srelease\son\sx64\swith\ngcc\s4.8.1\sand\s-Os. -D 2014-09-18T01:29:11.287 +C Make\ssure\sof\sthe\sstrchrnul()\slibrary\sfunction\son\splatforms\swhere\sit\sis\navailable. +D 2014-09-18T01:50:09.699 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -222,7 +222,7 @@ F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196 -F src/printf.c e74925089a85e3c9f0e315595f41c139d3d118c2 +F src/printf.c 19e3e81addf593195369ec8d487ed063ad3170bb F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e @@ -1198,8 +1198,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 8fb90da77ce0e662c1ef1ae0d854e5164494b7af 163bfae8583b2d3002a3a43d6bf8a66fefd73acb -R fdb25cd80d01110b7b302f5203339ac7 -T +closed 163bfae8583b2d3002a3a43d6bf8a66fefd73acb +P 1de558bcb13edc4e9a42a0b05e4b0ed6b14286a4 +R 5de5c16595c1a6599607c0d453169480 U drh -Z a578f94c122b57df374e40cc66ef0667 +Z 45b315c664f0110e7c4a00564360b273 diff --git a/manifest.uuid b/manifest.uuid index 5bbe565c7b..c029a6ebc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1de558bcb13edc4e9a42a0b05e4b0ed6b14286a4 \ No newline at end of file +ef1aa10b7f54912cba71cd0a98c5055d501de54f \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 8e71ad8bc6..03e39085b9 100644 --- a/src/printf.c +++ b/src/printf.c @@ -14,6 +14,21 @@ */ #include "sqliteInt.h" +/* +** If the strchrnul() library function is available, then set +** HAVE_STRCHRNUL. If that routine is not available, this module +** will supply its own. The built-in version is slower than +** the glibc version so the glibc version is definitely preferred. +*/ +#if !defined(HAVE_STRCHRNUL) +# if defined(__linux__) && defined(_GNU_SOURCE) +# define HAVE_STRCHRNUL 1 +# else +# define HAVE_STRCHRNUL 0 +# endif +#endif + + /* ** Conversion types fall into various categories as defined by the ** following enumeration. @@ -224,9 +239,13 @@ void sqlite3VXPrintf( for(; (c=(*fmt))!=0; ++fmt){ if( c!='%' ){ bufpt = (char *)fmt; - while( (c=(*++fmt))!='%' && c!=0 ){}; +#if HAVE_STRCHRNUL + fmt = strchrnul(fmt, '%'); +#else + do{ fmt++; }while( *fmt && *fmt != '%' ); +#endif sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt)); - if( c==0 ) break; + if( *fmt==0 ) break; } if( (c=(*++fmt))==0 ){ sqlite3StrAccumAppend(pAccum, "%", 1); From 20f3df046abb2da2c2030a89bbc23e3ad8b36f21 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Sep 2014 02:20:54 +0000 Subject: [PATCH 39/65] Fix harmless warnings on 32-bit MSVC builds. FossilOrigin-Name: 5192f964b2a85459553f1cea741b9791606ccc4e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/malloc.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f1b8ecd79c..2699c2c1a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sof\sthe\sstrchrnul()\slibrary\sfunction\son\splatforms\swhere\sit\sis\navailable. -D 2014-09-18T01:50:09.699 +C Fix\sharmless\swarnings\son\s32-bit\sMSVC\sbuilds. +D 2014-09-18T02:20:54.689 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -194,7 +194,7 @@ F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994 F src/main.c d15621461fb0c52675eba2b650492ed1beef69ab -F src/malloc.c c6dc1e154eb7d4a33eb737bde2c4103d00007597 +F src/malloc.c 4c1d511157defd7b1d023062cf05a1dc17b8f79b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f @@ -1198,7 +1198,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 1de558bcb13edc4e9a42a0b05e4b0ed6b14286a4 -R 5de5c16595c1a6599607c0d453169480 +P ef1aa10b7f54912cba71cd0a98c5055d501de54f +R c34bfcc3b603f9401507c43eeaad2e7b U drh -Z 45b315c664f0110e7c4a00564360b273 +Z e8711818b1e0ba1f2fd0d1d927b89d2c diff --git a/manifest.uuid b/manifest.uuid index c029a6ebc7..290fa02af4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef1aa10b7f54912cba71cd0a98c5055d501de54f \ No newline at end of file +5192f964b2a85459553f1cea741b9791606ccc4e \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index a4acd2f0ce..e0d5b5ff9d 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -599,7 +599,7 @@ void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ void *sqlite3MallocZero(u64 n){ void *p = sqlite3Malloc(n); if( p ){ - memset(p, 0, n); + memset(p, 0, (size_t)n); } return p; } @@ -611,7 +611,7 @@ void *sqlite3MallocZero(u64 n){ void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ void *p = sqlite3DbMallocRaw(db, n); if( p ){ - memset(p, 0, n); + memset(p, 0, (size_t)n); } return p; } @@ -753,7 +753,7 @@ char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ assert( (n&0x7fffffff)==n ); zNew = sqlite3DbMallocRaw(db, n+1); if( zNew ){ - memcpy(zNew, z, n); + memcpy(zNew, z, (size_t)n); zNew[n] = 0; } return zNew; From 9675d5dabc180230557a53faac66263a2f52477d Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Sep 2014 09:59:28 +0000 Subject: [PATCH 40/65] Modify an assert() within sqlite3PagerWalFramesize(), a function only ever used by zipvfs, to account for recent zipvfs changes. FossilOrigin-Name: 3bd7c1b2faa2d4cc95b255633204006849bfd5e0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2699c2c1a8..c14922f59d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\swarnings\son\s32-bit\sMSVC\sbuilds. -D 2014-09-18T02:20:54.689 +C Modify\san\sassert()\swithin\ssqlite3PagerWalFramesize(),\sa\sfunction\sonly\sever\sused\sby\szipvfs,\sto\saccount\sfor\srecent\szipvfs\schanges. +D 2014-09-18T09:59:28.052 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -214,7 +214,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 c6c809987f0c6a4e27634099d062d425527de173 +F src/pager.c caab007743821d96752597c9cfd7351654697b06 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c 4121a0571c18581ee9f82f086d5e2030051ebd6a @@ -1198,7 +1198,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 ef1aa10b7f54912cba71cd0a98c5055d501de54f -R c34bfcc3b603f9401507c43eeaad2e7b -U drh -Z e8711818b1e0ba1f2fd0d1d927b89d2c +P 5192f964b2a85459553f1cea741b9791606ccc4e +R e8be2bb63b11cad540f46beed0dd6c95 +U dan +Z 6d111ffcef80c669aed6101b87cfb783 diff --git a/manifest.uuid b/manifest.uuid index 290fa02af4..273ff9d0ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5192f964b2a85459553f1cea741b9791606ccc4e \ No newline at end of file +3bd7c1b2faa2d4cc95b255633204006849bfd5e0 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 6ad6f73227..79bfe15f10 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7230,7 +7230,7 @@ int sqlite3PagerCloseWal(Pager *pPager){ ** is empty, return 0. */ int sqlite3PagerWalFramesize(Pager *pPager){ - assert( pPager->eState==PAGER_READER ); + assert( pPager->eState>=PAGER_READER ); return sqlite3WalFramesize(pPager->pWal); } #endif From 7ea31ccb015703f08ba29b328f79182c6ee2b557 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Sep 2014 14:36:00 +0000 Subject: [PATCH 41/65] Since numeric affinity is the most common case, check it first. Interchange the NONE and TEXT affinity codes for easier checking of no affinity. FossilOrigin-Name: 4ef4c9a7c8510203bce0941dda2f76ded8da1de2 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 12 ++++++------ src/sqliteInt.h | 6 +++--- src/vdbe.c | 22 +++++++++++----------- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index c14922f59d..00c2f35ee9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\san\sassert()\swithin\ssqlite3PagerWalFramesize(),\sa\sfunction\sonly\sever\sused\sby\szipvfs,\sto\saccount\sfor\srecent\szipvfs\schanges. -D 2014-09-18T09:59:28.052 +C Since\snumeric\saffinity\sis\sthe\smost\scommon\scase,\scheck\sit\sfirst.\s\sInterchange\nthe\sNONE\sand\sTEXT\saffinity\scodes\sfor\seasier\schecking\sof\sno\saffinity. +D 2014-09-18T14:36:00.055 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 6aa61c0e3d20d1d1acc8fb33d8f0ebd675305d3c F src/btree.h a79aa6a71e7f1055f01052b7f821bd1c2dce95c8 F src/btreeInt.h e0ecb5dba292722039a7540beb3fc448103273cc -F src/build.c 047d7e1d2d89fa55134fa1d6b669c9c2983c0d11 +F src/build.c 8dbca25988045fbf2a33c9631c42706fa6449e60 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c 535183afb3c75628b78ce82612931ac7cdf26f14 F src/ctime.c 16cd19215d9fd849ee2b7509b092f2e0bbd6a958 @@ -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 0803e900eb1882f7dd88e86ddcddd2d1b27c8d86 +F src/sqliteInt.h 9bb8f655b076e1b9ed7cfe0b8c181e758d937369 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb @@ -288,7 +288,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 78606777e4ce5dba147ab75e71c0127b0d8d4c3d +F src/vdbe.c 2caa3b1e32f3fddc60fecb2cfd66afe2c2eb96b1 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f90b0de6153f50de630a5a113537efb47083812f F src/vdbeapi.c c02242df5e9e8d1001e0086f405953833f9c426b @@ -1198,7 +1198,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 5192f964b2a85459553f1cea741b9791606ccc4e -R e8be2bb63b11cad540f46beed0dd6c95 -U dan -Z 6d111ffcef80c669aed6101b87cfb783 +P 3bd7c1b2faa2d4cc95b255633204006849bfd5e0 +R c1df8072077a2642e4ce7426502f62dc +U drh +Z 04ecbaaf95d3fdde0c1a120923b44258 diff --git a/manifest.uuid b/manifest.uuid index 273ff9d0ee..2c7c5a518e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bd7c1b2faa2d4cc95b255633204006849bfd5e0 \ No newline at end of file +4ef4c9a7c8510203bce0941dda2f76ded8da1de2 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 791f6f2033..0c02a56fe7 100644 --- a/src/build.c +++ b/src/build.c @@ -1177,7 +1177,7 @@ char sqlite3AffinityType(const char *zIn, u8 *pszEst){ ** estimate is scaled so that the size of an integer is 1. */ if( pszEst ){ *pszEst = 1; /* default size is approx 4 bytes */ - if( aff<=SQLITE_AFF_NONE ){ + if( affaCol, i=0; inCol; i++, pCol++){ static const char * const azType[] = { - /* SQLITE_AFF_TEXT */ " TEXT", /* SQLITE_AFF_NONE */ "", + /* SQLITE_AFF_TEXT */ " TEXT", /* SQLITE_AFF_NUMERIC */ " NUM", /* SQLITE_AFF_INTEGER */ " INT", /* SQLITE_AFF_REAL */ " REAL" @@ -1561,15 +1561,15 @@ static char *createTableStmt(sqlite3 *db, Table *p){ k += sqlite3Strlen30(&zStmt[k]); zSep = zSep2; identPut(zStmt, &k, pCol->zName); - assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 ); - assert( pCol->affinity-SQLITE_AFF_TEXT < ArraySize(azType) ); - testcase( pCol->affinity==SQLITE_AFF_TEXT ); + assert( pCol->affinity-SQLITE_AFF_NONE >= 0 ); + assert( pCol->affinity-SQLITE_AFF_NONE < ArraySize(azType) ); testcase( pCol->affinity==SQLITE_AFF_NONE ); + testcase( pCol->affinity==SQLITE_AFF_TEXT ); testcase( pCol->affinity==SQLITE_AFF_NUMERIC ); testcase( pCol->affinity==SQLITE_AFF_INTEGER ); testcase( pCol->affinity==SQLITE_AFF_REAL ); - zType = azType[pCol->affinity - SQLITE_AFF_TEXT]; + zType = azType[pCol->affinity - SQLITE_AFF_NONE]; len = sqlite3Strlen30(zType); assert( pCol->affinity==SQLITE_AFF_NONE || pCol->affinity==sqlite3AffinityType(zType, 0) ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fd3731d817..ea8ad4573f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1427,10 +1427,10 @@ struct CollSeq { ** used as the P4 operand, they will be more readable. ** ** Note also that the numeric types are grouped together so that testing -** for a numeric type is a single comparison. +** for a numeric type is a single comparison. And the NONE type is first. */ -#define SQLITE_AFF_TEXT 'a' -#define SQLITE_AFF_NONE 'b' +#define SQLITE_AFF_NONE 'a' +#define SQLITE_AFF_TEXT 'b' #define SQLITE_AFF_NUMERIC 'c' #define SQLITE_AFF_INTEGER 'd' #define SQLITE_AFF_REAL 'e' diff --git a/src/vdbe.c b/src/vdbe.c index f964a73878..1ff33b3e49 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -277,15 +277,7 @@ static void applyAffinity( char affinity, /* The affinity to be applied */ u8 enc /* Use this text encoding */ ){ - if( affinity==SQLITE_AFF_TEXT ){ - /* Only attempt the conversion to TEXT if there is an integer or real - ** representation (blob and NULL do not get converted) but no string - ** representation. - */ - if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ - sqlite3VdbeMemStringify(pRec, enc, 1); - } - }else if( affinity!=SQLITE_AFF_NONE ){ + if( affinity>=SQLITE_AFF_NUMERIC ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL || affinity==SQLITE_AFF_NUMERIC ); if( (pRec->flags & MEM_Int)==0 ){ @@ -295,6 +287,14 @@ static void applyAffinity( sqlite3VdbeIntegerAffinity(pRec); } } + }else if( affinity==SQLITE_AFF_TEXT ){ + /* Only attempt the conversion to TEXT if there is an integer or real + ** representation (blob and NULL do not get converted) but no string + ** representation. + */ + if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ + sqlite3VdbeMemStringify(pRec, enc, 1); + } } } @@ -1754,7 +1754,7 @@ case OP_RealAffinity: { /* in1 */ ** A NULL value is not changed by this routine. It remains NULL. */ case OP_Cast: { /* in1 */ - assert( pOp->p2>=SQLITE_AFF_TEXT && pOp->p2<=SQLITE_AFF_REAL ); + assert( pOp->p2>=SQLITE_AFF_NONE && pOp->p2<=SQLITE_AFF_REAL ); testcase( pOp->p2==SQLITE_AFF_TEXT ); testcase( pOp->p2==SQLITE_AFF_NONE ); testcase( pOp->p2==SQLITE_AFF_NUMERIC ); @@ -1904,7 +1904,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ }else{ /* Neither operand is NULL. Do a comparison. */ affinity = pOp->p5 & SQLITE_AFF_MASK; - if( affinity ){ + if( affinity>=SQLITE_AFF_TEXT ){ applyAffinity(pIn1, affinity, encoding); applyAffinity(pIn3, affinity, encoding); if( db->mallocFailed ) goto no_mem; From 24a096297ef66348e059b07328f1beb466b5e7c9 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Sep 2014 16:28:59 +0000 Subject: [PATCH 42/65] Performance improvement for affinity transformations on comparison operators. FossilOrigin-Name: d7afdcbac24350b73a30c06c45cf0f2122820e4f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 20 +++++++++++++++----- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 00c2f35ee9..8cf00918c0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Since\snumeric\saffinity\sis\sthe\smost\scommon\scase,\scheck\sit\sfirst.\s\sInterchange\nthe\sNONE\sand\sTEXT\saffinity\scodes\sfor\seasier\schecking\sof\sno\saffinity. -D 2014-09-18T14:36:00.055 +C Performance\simprovement\sfor\saffinity\stransformations\son\scomparison\soperators. +D 2014-09-18T16:28:59.796 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 2caa3b1e32f3fddc60fecb2cfd66afe2c2eb96b1 +F src/vdbe.c b00ffadc43a588b02ca2b60b9128338a6f4efcba F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f90b0de6153f50de630a5a113537efb47083812f F src/vdbeapi.c c02242df5e9e8d1001e0086f405953833f9c426b @@ -1198,7 +1198,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 3bd7c1b2faa2d4cc95b255633204006849bfd5e0 -R c1df8072077a2642e4ce7426502f62dc +P 4ef4c9a7c8510203bce0941dda2f76ded8da1de2 +R b808ae1c5ded91d91c2a612e5497b640 U drh -Z 04ecbaaf95d3fdde0c1a120923b44258 +Z 8ec5fac053656715ec4b7b6a3b299333 diff --git a/manifest.uuid b/manifest.uuid index 2c7c5a518e..8fa5f719ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ef4c9a7c8510203bce0941dda2f76ded8da1de2 \ No newline at end of file +d7afdcbac24350b73a30c06c45cf0f2122820e4f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1ff33b3e49..4bfa5f0e7e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1904,12 +1904,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ }else{ /* Neither operand is NULL. Do a comparison. */ affinity = pOp->p5 & SQLITE_AFF_MASK; - if( affinity>=SQLITE_AFF_TEXT ){ - applyAffinity(pIn1, affinity, encoding); - applyAffinity(pIn3, affinity, encoding); - if( db->mallocFailed ) goto no_mem; + if( affinity>=SQLITE_AFF_NUMERIC ){ + if( (pIn1->flags & (MEM_Int|MEM_Real))==0 && (pIn1->flags&MEM_Str)!=0 ){ + applyNumericAffinity(pIn1,0); + } + if( (pIn3->flags & (MEM_Int|MEM_Real))==0 && (pIn3->flags&MEM_Str)!=0 ){ + applyNumericAffinity(pIn3,0); + } + }else if( affinity==SQLITE_AFF_TEXT ){ + if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){ + sqlite3VdbeMemStringify(pIn1, encoding, 1); + } + if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){ + sqlite3VdbeMemStringify(pIn3, encoding, 1); + } } - assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); if( pIn1->flags & MEM_Zero ){ sqlite3VdbeMemExpandBlob(pIn1); @@ -1919,6 +1928,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemExpandBlob(pIn3); flags3 &= ~MEM_Zero; } + if( db->mallocFailed ) goto no_mem; res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } switch( pOp->opcode ){ From 74eaba4de25d955314df279e5ca27aa24f2698ea Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Sep 2014 17:52:15 +0000 Subject: [PATCH 43/65] Merge the Mem.r value into the MemValue union as Mem.u.r. Hence, a Mem can now store an integer or a real but not both at the same time. Strings are still stored in a separate element Mem.z, for now. FossilOrigin-Name: 4c8c89d7e62aecfe2eb735f7bb114aed6b452847 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/vdbe.c | 19 ++++++++++--------- src/vdbeInt.h | 6 +++--- src/vdbeapi.c | 3 +-- src/vdbeaux.c | 24 ++++++++++++------------ src/vdbemem.c | 36 +++++++++++++++++++----------------- src/vdbetrace.c | 2 +- 8 files changed, 58 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index 8cf00918c0..4bfcb72630 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sfor\saffinity\stransformations\son\scomparison\soperators. -D 2014-09-18T16:28:59.796 +C Merge\sthe\sMem.r\svalue\sinto\sthe\sMemValue\sunion\sas\sMem.u.r.\s\sHence,\sa\sMem\scan\nnow\sstore\san\sinteger\sor\sa\sreal\sbut\snot\sboth\sat\sthe\ssame\stime.\s\sStrings\sare\nstill\sstored\sin\sa\sseparate\selement\sMem.z,\sfor\snow. +D 2014-09-18T17:52:15.374 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,15 +288,15 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c b00ffadc43a588b02ca2b60b9128338a6f4efcba +F src/vdbe.c 17f285ff89d73b6af5bd1fc90c0943341f4003d5 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h f90b0de6153f50de630a5a113537efb47083812f -F src/vdbeapi.c c02242df5e9e8d1001e0086f405953833f9c426b -F src/vdbeaux.c 9ac63bc59d2783df77e591e4c4fa8c1153a07eab +F src/vdbeInt.h 45a0b4c5e4b38a2ff8af05102d45e7fa2e6c4439 +F src/vdbeapi.c 88929e02676fdbd5f436fcfd63fa0d371756a7ce +F src/vdbeaux.c ac3188f182f25eac58923b1a3c0840c69949ed28 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 8b5e1083fed2da94e315858a7edf5604a5b91804 +F src/vdbemem.c 1907e24ab431bd465f5709c30ec28a9119502f9a F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde -F src/vdbetrace.c 16d39c1ef7d1f4a3a7464bea3b7b4bdd7849c415 +F src/vdbetrace.c 4f29b04edb0cec3d5fcd9b566d9f0e75c8984362 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 @@ -1198,7 +1198,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 4ef4c9a7c8510203bce0941dda2f76ded8da1de2 -R b808ae1c5ded91d91c2a612e5497b640 +P d7afdcbac24350b73a30c06c45cf0f2122820e4f +R 320866568edfdafc16dd0b942dd87d16 U drh -Z 8ec5fac053656715ec4b7b6a3b299333 +Z 7641aa17b0b2d51a4b828447b0d0dc99 diff --git a/manifest.uuid b/manifest.uuid index 8fa5f719ed..55f0527798 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d7afdcbac24350b73a30c06c45cf0f2122820e4f \ No newline at end of file +4c8c89d7e62aecfe2eb735f7bb114aed6b452847 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 4bfa5f0e7e..996cf8b9b8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -243,12 +243,13 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ i64 iValue; u8 enc = pRec->enc; if( (pRec->flags&MEM_Str)==0 ) return; + if( (pRec->flags&(MEM_Int|MEM_Real))!=0 ) return; if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ pRec->u.i = iValue; pRec->flags |= MEM_Int; }else{ - pRec->r = rValue; + pRec->u.r = rValue; pRec->flags |= MEM_Real; if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); } @@ -329,13 +330,13 @@ void sqlite3ValueApplyAffinity( /* ** pMem currently only holds a string type (or maybe a BLOB that we can ** interpret as a string if we want to). Compute its corresponding -** numeric type, if has one. Set the pMem->r and pMem->u.i fields +** numeric type, if has one. Set the pMem->u.r and pMem->u.i fields ** accordingly. */ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); - if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){ + if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ return 0; } if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){ @@ -349,7 +350,7 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ ** none. ** ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. -** But it does set pMem->r and pMem->u.i appropriately. +** But it does set pMem->u.r and pMem->u.i appropriately. */ static u16 numericType(Mem *pMem){ if( pMem->flags & (MEM_Int|MEM_Real) ){ @@ -459,7 +460,7 @@ static void memTracePrint(Mem *p){ printf(" i:%lld", p->u.i); #ifndef SQLITE_OMIT_FLOATING_POINT }else if( p->flags & MEM_Real ){ - printf(" r:%g", p->r); + printf(" r:%g", p->u.r); #endif }else if( p->flags & MEM_RowSet ){ printf(" (rowset)"); @@ -1002,7 +1003,7 @@ case OP_Int64: { /* out2-prerelease */ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */ pOut->flags = MEM_Real; assert( !sqlite3IsNaN(*pOp->p4.pReal) ); - pOut->r = *pOp->p4.pReal; + pOut->u.r = *pOp->p4.pReal; break; } #endif @@ -1479,7 +1480,7 @@ fp_math: if( sqlite3IsNaN(rB) ){ goto arithmetic_result_is_null; } - pOut->r = rB; + pOut->u.r = rB; MemSetTypeFlag(pOut, MEM_Real); if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ sqlite3VdbeIntegerAffinity(pOut); @@ -3572,7 +3573,7 @@ case OP_SeekGT: { /* jump, in3 */ ** (x > 4.9) -> (x >= 5) ** (x <= 4.9) -> (x < 5) */ - if( pIn3->r<(double)iKey ){ + if( pIn3->u.r<(double)iKey ){ assert( OP_SeekGE==(OP_SeekGT-1) ); assert( OP_SeekLT==(OP_SeekLE-1) ); assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); @@ -3581,7 +3582,7 @@ case OP_SeekGT: { /* jump, in3 */ /* If the approximation iKey is smaller than the actual real search ** term, substitute <= for < and > for >=. */ - else if( pIn3->r>(double)iKey ){ + else if( pIn3->u.r>(double)iKey ){ assert( OP_SeekLE==(OP_SeekLT+1) ); assert( OP_SeekGT==(OP_SeekGE+1) ); assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 9c7378a26c..fb05e9aed2 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -161,7 +161,8 @@ struct VdbeFrame { ** integer etc.) of the same value. */ struct Mem { - union { + union MemValue { + double r; /* Real value used when MEM_Realis set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Used when bit MEM_Zero is set in flags */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ @@ -171,10 +172,9 @@ struct Mem { u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ int n; /* Number of characters in string value, excluding '\0' */ - double r; /* Real value */ char *z; /* String or BLOB value */ - char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ /* ShallowCopy only needs to copy the information above */ + char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ sqlite3 *db; /* The associated database connection */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG diff --git a/src/vdbeapi.c b/src/vdbeapi.c index ef1167a52d..aad64aa64b 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -807,7 +807,6 @@ static const Mem *columnNullValue(void){ /* .flags = */ MEM_Null, /* .enc = */ 0, /* .n = */ 0, - /* .r = */ (double)0, /* .z = */ 0, /* .zMalloc = */ 0, /* .db = */ 0, @@ -1272,7 +1271,7 @@ int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ break; } case SQLITE_FLOAT: { - rc = sqlite3_bind_double(pStmt, i, pValue->r); + rc = sqlite3_bind_double(pStmt, i, pValue->u.r); break; } case SQLITE_BLOB: { diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8466bfb30a..ad57f4ccd3 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1076,7 +1076,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ }else if( pMem->flags & MEM_Int ){ sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ - sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r); + sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r); }else if( pMem->flags & MEM_Null ){ sqlite3_snprintf(nTemp, zTemp, "NULL"); }else{ @@ -2949,8 +2949,8 @@ u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ u64 v; u32 i; if( serial_type==7 ){ - assert( sizeof(v)==sizeof(pMem->r) ); - memcpy(&v, &pMem->r, sizeof(v)); + assert( sizeof(v)==sizeof(pMem->u.r) ); + memcpy(&v, &pMem->u.r, sizeof(v)); swapMixedEndianFloat(v); }else{ v = pMem->u.i; @@ -3020,10 +3020,10 @@ static u32 SQLITE_NOINLINE serialGet( swapMixedEndianFloat(t2); assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 ); #endif - assert( sizeof(x)==8 && sizeof(pMem->r)==8 ); + assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 ); swapMixedEndianFloat(x); - memcpy(&pMem->r, &x, sizeof(x)); - pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real; + memcpy(&pMem->u.r, &x, sizeof(x)); + pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real; } return 8; } @@ -3368,14 +3368,14 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ return 0; } if( (f1&MEM_Real)!=0 ){ - r1 = pMem1->r; + r1 = pMem1->u.r; }else if( (f1&MEM_Int)!=0 ){ r1 = (double)pMem1->u.i; }else{ return 1; } if( (f2&MEM_Real)!=0 ){ - r2 = pMem2->r; + r2 = pMem2->u.r; }else if( (f2&MEM_Int)!=0 ){ r2 = (double)pMem2->u.i; }else{ @@ -3536,9 +3536,9 @@ static int vdbeRecordCompareWithSkip( }else if( serial_type==7 ){ double rhs = (double)pRhs->u.i; sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); - if( mem1.rrhs ){ + }else if( mem1.u.r>rhs ){ rc = +1; } }else{ @@ -3560,11 +3560,11 @@ static int vdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else{ - double rhs = pRhs->r; + double rhs = pRhs->u.r; double lhs; sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ - lhs = mem1.r; + lhs = mem1.u.r; }else{ lhs = (double)mem1.u.i; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 359abb891f..780bc5286b 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -31,6 +31,9 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ */ assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); + /* Cannot be both MEM_Int and MEM_Real at the same time */ + assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); + /* If p holds a string or blob, the Mem.z must point to exactly ** one of the following: ** @@ -264,7 +267,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i); }else{ assert( fg & MEM_Real ); - sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r); + sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); } pMem->n = sqlite3Strlen30(pMem->z); pMem->enc = SQLITE_UTF8; @@ -421,7 +424,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ if( flags & MEM_Int ){ return pMem->u.i; }else if( flags & MEM_Real ){ - return doubleToInt64(pMem->r); + return doubleToInt64(pMem->u.r); }else if( flags & (MEM_Str|MEM_Blob) ){ i64 value = 0; assert( pMem->z || pMem->n==0 ); @@ -442,7 +445,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( pMem->flags & MEM_Real ){ - return pMem->r; + return pMem->u.r; }else if( pMem->flags & MEM_Int ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ @@ -461,12 +464,13 @@ double sqlite3VdbeRealValue(Mem *pMem){ ** MEM_Int if we can. */ void sqlite3VdbeIntegerAffinity(Mem *pMem){ + i64 ix; assert( pMem->flags & MEM_Real ); assert( (pMem->flags & MEM_RowSet)==0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - pMem->u.i = doubleToInt64(pMem->r); + ix = doubleToInt64(pMem->u.r); /* Only mark the value as an integer if ** @@ -478,11 +482,9 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){ ** the second condition under the assumption that addition overflow causes ** values to wrap around. */ - if( pMem->r==(double)pMem->u.i - && pMem->u.i>SMALLEST_INT64 - && pMem->u.iflags |= MEM_Int; + if( pMem->u.r==ix && ix>SMALLEST_INT64 && ixu.i = ix; + MemSetTypeFlag(pMem, MEM_Int); } } @@ -507,7 +509,7 @@ int sqlite3VdbeMemRealify(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - pMem->r = sqlite3VdbeRealValue(pMem); + pMem->u.r = sqlite3VdbeRealValue(pMem); MemSetTypeFlag(pMem, MEM_Real); return SQLITE_OK; } @@ -527,7 +529,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ MemSetTypeFlag(pMem, MEM_Int); }else{ - pMem->r = sqlite3VdbeRealValue(pMem); + pMem->u.r = sqlite3VdbeRealValue(pMem); MemSetTypeFlag(pMem, MEM_Real); sqlite3VdbeIntegerAffinity(pMem); } @@ -663,7 +665,7 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ sqlite3VdbeMemSetNull(pMem); if( !sqlite3IsNaN(val) ){ - pMem->r = val; + pMem->u.r = val; pMem->flags = MEM_Real; } } @@ -1168,14 +1170,14 @@ static int valueFromExpr( && pVal!=0 ){ sqlite3VdbeMemNumerify(pVal); - if( pVal->u.i==SMALLEST_INT64 ){ - pVal->flags &= ~MEM_Int; - pVal->flags |= MEM_Real; - pVal->r = (double)SMALLEST_INT64; + if( pVal->flags & MEM_Real ){ + pVal->u.r = -pVal->u.r; + }else if( pVal->u.i==SMALLEST_INT64 ){ + pVal->u.r = -(double)SMALLEST_INT64; + MemSetTypeFlag(pVal, MEM_Real); }else{ pVal->u.i = -pVal->u.i; } - pVal->r = -pVal->r; sqlite3ValueApplyAffinity(pVal, affinity, enc); } }else if( op==TK_NULL ){ diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 362530a1d9..d27693450e 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -127,7 +127,7 @@ char *sqlite3VdbeExpandSql( }else if( pVar->flags & MEM_Int ){ sqlite3XPrintf(&out, 0, "%lld", pVar->u.i); }else if( pVar->flags & MEM_Real ){ - sqlite3XPrintf(&out, 0, "%!.15g", pVar->r); + sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r); }else if( pVar->flags & MEM_Str ){ int nOut; /* Number of bytes of the string text to include in output */ #ifndef SQLITE_OMIT_UTF16 From 26c79a060b2e7fdf6d05585a3b44d0498df3fe1c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 18 Sep 2014 18:55:47 +0000 Subject: [PATCH 44/65] Correct typos in comments. No changes to code. FossilOrigin-Name: 55879932116d373c95a5f32ec44b53a9c3f4db24 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeInt.h | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 4bfcb72630..f3e0c0137b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sMem.r\svalue\sinto\sthe\sMemValue\sunion\sas\sMem.u.r.\s\sHence,\sa\sMem\scan\nnow\sstore\san\sinteger\sor\sa\sreal\sbut\snot\sboth\sat\sthe\ssame\stime.\s\sStrings\sare\nstill\sstored\sin\sa\sseparate\selement\sMem.z,\sfor\snow. -D 2014-09-18T17:52:15.374 +C Correct\stypos\sin\scomments.\s\sNo\schanges\sto\scode. +D 2014-09-18T18:55:47.619 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -290,7 +290,7 @@ F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a F src/vdbe.c 17f285ff89d73b6af5bd1fc90c0943341f4003d5 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h 45a0b4c5e4b38a2ff8af05102d45e7fa2e6c4439 +F src/vdbeInt.h 1c31448d9d4f074e93863ebe69164ff29cc4f7f8 F src/vdbeapi.c 88929e02676fdbd5f436fcfd63fa0d371756a7ce F src/vdbeaux.c ac3188f182f25eac58923b1a3c0840c69949ed28 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 @@ -1198,7 +1198,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 d7afdcbac24350b73a30c06c45cf0f2122820e4f -R 320866568edfdafc16dd0b942dd87d16 -U drh -Z 7641aa17b0b2d51a4b828447b0d0dc99 +P 4c8c89d7e62aecfe2eb735f7bb114aed6b452847 +R a232caa53ffd8c1fd2d0c9fb51cf1463 +U mistachkin +Z b2beb30c7e105753dffdcae3bc62d871 diff --git a/manifest.uuid b/manifest.uuid index 55f0527798..cd35e4dca6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c8c89d7e62aecfe2eb735f7bb114aed6b452847 \ No newline at end of file +55879932116d373c95a5f32ec44b53a9c3f4db24 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index fb05e9aed2..8e4405437b 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -162,7 +162,7 @@ struct VdbeFrame { */ struct Mem { union MemValue { - double r; /* Real value used when MEM_Realis set in flags */ + double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ int nZero; /* Used when bit MEM_Zero is set in flags */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ @@ -268,13 +268,13 @@ struct AuxData { */ struct sqlite3_context { Mem *pOut; /* The return value is stored here */ - FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */ + FuncDef *pFunc; /* Pointer to function information */ Mem *pMem; /* Memory cell used to store aggregate context */ CollSeq *pColl; /* Collating sequence */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ - u8 skipFlag; /* Skip skip accumulator loading if true */ + u8 skipFlag; /* Skip accumulator loading if true */ u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ }; From 17bcb102993a155dec69a58e2f079a880e1967b7 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Sep 2014 21:25:33 +0000 Subject: [PATCH 45/65] Add the Mem.szMalloc element to the Mem object and use it to keep track of the size of the Mem.zMalloc allocation. FossilOrigin-Name: 9c09ac353df6041808cace41880f4729ee73f5e1 --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/malloc.c | 19 +++++++++++-------- src/test_func.c | 4 ++-- src/utf.c | 1 + src/vdbe.c | 11 +++-------- src/vdbeInt.h | 4 +++- src/vdbeapi.c | 2 ++ src/vdbeaux.c | 29 ++++++++++++++--------------- src/vdbemem.c | 41 ++++++++++++++++++++++++++--------------- 10 files changed, 77 insertions(+), 64 deletions(-) diff --git a/manifest b/manifest index f3e0c0137b..1ced1cbf05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correct\stypos\sin\scomments.\s\sNo\schanges\sto\scode. -D 2014-09-18T18:55:47.619 +C Add\sthe\sMem.szMalloc\selement\sto\sthe\sMem\sobject\sand\suse\sit\sto\skeep\strack\sof\nthe\ssize\sof\sthe\sMem.zMalloc\sallocation. +D 2014-09-18T21:25:33.845 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -194,7 +194,7 @@ F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994 F src/main.c d15621461fb0c52675eba2b650492ed1beef69ab -F src/malloc.c 4c1d511157defd7b1d023062cf05a1dc17b8f79b +F src/malloc.c 5bb99ee1e08ad58e457063cf79ce521db0e24195 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f @@ -253,7 +253,7 @@ F src/test_config.c 6f721f0337b96d58e81ff69bba101113c8168c2b F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f -F src/test_func.c d3013ce36f19ac72a99c73864930fd1fa41832f8 +F src/test_func.c 14e543ae4d905ee31dc322b2f8d31bfac1769d45 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_intarray.c 6c610a21ab8edde85a3a2c7f2b069244ecf4d834 @@ -285,16 +285,16 @@ F src/threads.c 22dded4283dc4b25422f6444cdcb8d6b1ea0b5ff F src/tokenize.c 3df63041994f55afeb168b463ec836e8f1c50e7c F src/trigger.c 25571661fdeae8c7f975ff40ffec205520a3f92f F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 -F src/utf.c 8f634b93d41c089029dd503161a7d3e685d59a9c +F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 17f285ff89d73b6af5bd1fc90c0943341f4003d5 +F src/vdbe.c fb490f5b1b2ee2f33f60c7dc678c0d0b70f2e0cb F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h 1c31448d9d4f074e93863ebe69164ff29cc4f7f8 -F src/vdbeapi.c 88929e02676fdbd5f436fcfd63fa0d371756a7ce -F src/vdbeaux.c ac3188f182f25eac58923b1a3c0840c69949ed28 +F src/vdbeInt.h 1ac536d1fa1260d72f81003ff5b283e8f3c40442 +F src/vdbeapi.c e088ed70b6cc42ed68985ab064397ebd452286d6 +F src/vdbeaux.c b3230032238df611aefee5907ea792786362a55d F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 1907e24ab431bd465f5709c30ec28a9119502f9a +F src/vdbemem.c 3aea3831a981378368ca058cd8fc700b1982772d F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde F src/vdbetrace.c 4f29b04edb0cec3d5fcd9b566d9f0e75c8984362 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 4c8c89d7e62aecfe2eb735f7bb114aed6b452847 -R a232caa53ffd8c1fd2d0c9fb51cf1463 -U mistachkin -Z b2beb30c7e105753dffdcae3bc62d871 +P 55879932116d373c95a5f32ec44b53a9c3f4db24 +R 508057a57cef866ce62608d1eb2d9e8e +U drh +Z 7d8fd1db974daf115bf085d0714b6de9 diff --git a/manifest.uuid b/manifest.uuid index cd35e4dca6..77cd05df09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55879932116d373c95a5f32ec44b53a9c3f4db24 \ No newline at end of file +9c09ac353df6041808cace41880f4729ee73f5e1 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index e0d5b5ff9d..8ba5fa0a84 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -451,15 +451,18 @@ int sqlite3MallocSize(void *p){ return sqlite3GlobalConfig.m.xSize(p); } int sqlite3DbMallocSize(sqlite3 *db, void *p){ - assert( db!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); - if( isLookaside(db, p) ){ - return db->lookaside.sz; + if( db==0 ){ + return sqlite3MallocSize(p); }else{ - assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); - assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); - assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); - return sqlite3GlobalConfig.m.xSize(p); + assert( sqlite3_mutex_held(db->mutex) ); + if( isLookaside(db, p) ){ + return db->lookaside.sz; + }else{ + assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + return sqlite3GlobalConfig.m.xSize(p); + } } } sqlite3_uint64 sqlite3_msize(void *p){ diff --git a/src/test_func.c b/src/test_func.c index 9cf2f8002c..c7850631d7 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -504,7 +504,7 @@ static void test_extract( sqlite3_result_value(context, &mem); } - sqlite3DbFree(db, mem.zMalloc); + if( mem.szMalloc ) sqlite3DbFree(db, mem.zMalloc); } } @@ -591,7 +591,7 @@ static void test_decode( Tcl_ListObjAppendElement(0, pRet, pVal); - if( mem.zMalloc ){ + if( mem.szMalloc ){ sqlite3DbFree(db, mem.zMalloc); } } diff --git a/src/utf.c b/src/utf.c index 549983f6f1..25f4dadf0c 100644 --- a/src/utf.c +++ b/src/utf.c @@ -320,6 +320,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ pMem->enc = desiredEnc; pMem->z = (char*)zOut; pMem->zMalloc = pMem->z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z); translate_out: #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) diff --git a/src/vdbe.c b/src/vdbe.c index 996cf8b9b8..4a63f30af8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1026,9 +1026,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); if( rc==SQLITE_TOOBIG ) goto too_big; if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; - assert( pOut->zMalloc==pOut->z ); + assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); assert( VdbeMemDynamic(pOut)==0 ); - pOut->zMalloc = 0; + pOut->szMalloc = 0; pOut->flags |= MEM_Static; if( pOp->p4type==P4_DYNAMIC ){ sqlite3DbFree(db, pOp->p4.z); @@ -1148,7 +1148,6 @@ case OP_Variable: { /* out2-prerelease */ ** for P3 to be less than 1. */ case OP_Move: { - char *zMalloc; /* Holding variable for allocated memory */ int n; /* Number of registers left to copy */ int p1; /* Register to copy from */ int p2; /* Register to copy to */ @@ -1166,16 +1165,12 @@ case OP_Move: { assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); assert( memIsValid(pIn1) ); memAboutToChange(p, pOut); - sqlite3VdbeMemRelease(pOut); - zMalloc = pOut->zMalloc; - memcpy(pOut, pIn1, sizeof(Mem)); + sqlite3VdbeMemMove(pOut, pIn1); #ifdef SQLITE_DEBUG if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){ pOut->pScopyFrom += p1 - pOp->p2; } #endif - pIn1->flags = MEM_Undefined; - pIn1->zMalloc = zMalloc; REGISTER_TRACE(p2++, pOut); pIn1++; pOut++; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 8e4405437b..138e61d2c2 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -174,7 +174,9 @@ struct Mem { int n; /* Number of characters in string value, excluding '\0' */ char *z; /* String or BLOB value */ /* ShallowCopy only needs to copy the information above */ - char *zMalloc; /* Dynamic buffer allocated by sqlite3_malloc() */ + char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ + int szMalloc; /* Size of the zMalloc allocation */ + int iPadding1; /* Padding for 8-byte alignment */ sqlite3 *db; /* The associated database connection */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG diff --git a/src/vdbeapi.c b/src/vdbeapi.c index aad64aa64b..7d3ae9cb07 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -809,6 +809,8 @@ static const Mem *columnNullValue(void){ /* .n = */ 0, /* .z = */ 0, /* .zMalloc = */ 0, + /* .szMalloc = */ 0, + /* .iPadding1 = */ 0, /* .db = */ 0, /* .xDel = */ 0, #ifdef SQLITE_DEBUG diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ad57f4ccd3..f990c40d41 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -698,7 +698,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ sqlite3ValueFree((sqlite3_value*)p4); }else{ Mem *p = (Mem*)p4; - sqlite3DbFree(db, p->zMalloc); + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); sqlite3DbFree(db, p); } break; @@ -1231,7 +1231,7 @@ static void releaseMemArray(Mem *p, int N){ u8 malloc_failed = db->mallocFailed; if( db->pnBytesFreed ){ for(pEnd=&p[N]; pzMalloc); + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); } return; } @@ -1257,9 +1257,9 @@ static void releaseMemArray(Mem *p, int N){ testcase( p->flags & MEM_RowSet ); if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ sqlite3VdbeMemRelease(p); - }else if( p->zMalloc ){ + }else if( p->szMalloc ){ sqlite3DbFree(db, p->zMalloc); - p->zMalloc = 0; + p->szMalloc = 0; } p->flags = MEM_Undefined; @@ -3167,7 +3167,7 @@ void sqlite3VdbeRecordUnpack( pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ - pMem->zMalloc = 0; + pMem->szMalloc = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; if( (++u)>=p->nField ) break; @@ -3207,7 +3207,7 @@ static int vdbeRecordCompareDebug( mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ - VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ /* Compilers may complain that mem1.u.i is potentially uninitialized. ** We could initialize it, as shown here, to silence those complaints. @@ -3250,7 +3250,7 @@ static int vdbeRecordCompareDebug( */ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]); if( rc!=0 ){ - assert( mem1.zMalloc==0 ); /* See comment below */ + assert( mem1.szMalloc==0 ); /* See comment below */ if( pKeyInfo->aSortOrder[i] ){ rc = -rc; /* Invert the result for DESC sort order. */ } @@ -3263,7 +3263,7 @@ static int vdbeRecordCompareDebug( ** the following assert(). If the assert() fails, it indicates a ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ - assert( mem1.zMalloc==0 ); + assert( mem1.szMalloc==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 default_rc @@ -3302,9 +3302,8 @@ static int vdbeCompareMemString( int n1, n2; Mem c1; Mem c2; - c1.db = c2.db = pMem1->db; - c1.flags = c2.flags = 0; - c1.zMalloc = c2.zMalloc = 0; + sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); + sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); @@ -3516,7 +3515,7 @@ static int vdbeRecordCompareWithSkip( i = 0; } - VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */ + VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB ); assert( pPKey2->pKeyInfo->aSortOrder!=0 ); @@ -3639,7 +3638,7 @@ static int vdbeRecordCompareWithSkip( rc = -rc; } assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); - assert( mem1.zMalloc==0 ); /* See comment below */ + assert( mem1.szMalloc==0 ); /* See comment below */ return rc; } @@ -3652,7 +3651,7 @@ static int vdbeRecordCompareWithSkip( /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ - assert( mem1.zMalloc==0 ); + assert( mem1.szMalloc==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 default_rc @@ -3937,7 +3936,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ /* Jump here if database corruption is detected after m has been ** allocated. Free the m object and return SQLITE_CORRUPT. */ idx_rowid_corruption: - testcase( m.zMalloc!=0 ); + testcase( m.szMalloc!=0 ); sqlite3VdbeMemRelease(&m); return SQLITE_CORRUPT_BKPT; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 780bc5286b..4ea28f841f 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -34,6 +34,10 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ /* Cannot be both MEM_Int and MEM_Real at the same time */ assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); + /* The szMalloc field holds the correct memory allocation size */ + assert( p->szMalloc==0 + || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) ); + /* If p holds a string or blob, the Mem.z must point to exactly ** one of the following: ** @@ -42,9 +46,9 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ ** (3) An ephemeral string or blob ** (4) A static string or blob */ - if( (p->flags & (MEM_Str|MEM_Blob)) && p->z!=0 ){ + if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){ assert( - ((p->z==p->zMalloc)? 1 : 0) + + ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) + ((p->flags&MEM_Dyn)!=0 ? 1 : 0) + ((p->flags&MEM_Ephem)!=0 ? 1 : 0) + ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1 @@ -112,19 +116,24 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) ); testcase( bPreserve && pMem->z==0 ); - if( pMem->zMalloc==0 || sqlite3DbMallocSize(pMem->db, pMem->zMalloc)szMalloc==0 + || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); + if( pMem->szMallocz==pMem->zMalloc ){ + if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); bPreserve = 0; }else{ - sqlite3DbFree(pMem->db, pMem->zMalloc); + if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); } if( pMem->zMalloc==0 ){ sqlite3VdbeMemSetNull(pMem); pMem->z = 0; + pMem->szMalloc = 0; return SQLITE_NOMEM; + }else{ + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); } } @@ -155,7 +164,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ assert( (pMem->flags&MEM_RowSet)==0 ); ExpandBlob(pMem); f = pMem->flags; - if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){ + if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){ if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){ return SQLITE_NOMEM; } @@ -301,7 +310,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ctx.pFunc = pFunc; pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ assert( (pMem->flags & MEM_Dyn)==0 ); - sqlite3DbFree(pMem->db, pMem->zMalloc); + if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc); memcpy(pMem, &t, sizeof(t)); rc = ctx.isError; } @@ -351,9 +360,9 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ if( VdbeMemDynamic(p) ){ vdbeMemClearExternAndSetNull(p); } - if( p->zMalloc ){ + if( p->szMalloc ){ sqlite3DbFree(p->db, p->zMalloc); - p->zMalloc = 0; + p->szMalloc = 0; } p->z = 0; } @@ -370,7 +379,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ */ void sqlite3VdbeMemRelease(Mem *p){ assert( sqlite3VdbeCheckMemInvariants(p) ); - if( VdbeMemDynamic(p) || p->zMalloc ){ + if( VdbeMemDynamic(p) || p->szMalloc ){ vdbeMemClear(p); } } @@ -592,7 +601,7 @@ void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){ assert( (flags & ~MEM_TypeMask)==0 ); pMem->flags = flags; pMem->db = db; - pMem->zMalloc = 0; + pMem->szMalloc = 0; } @@ -683,10 +692,11 @@ void sqlite3VdbeMemSetRowSet(Mem *pMem){ pMem->zMalloc = sqlite3DbMallocRaw(db, 64); if( db->mallocFailed ){ pMem->flags = MEM_Null; + pMem->szMalloc = 0; }else{ assert( pMem->zMalloc ); - pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, - sqlite3DbMallocSize(db, pMem->zMalloc)); + pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); + pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); assert( pMem->u.pRowSet!=0 ); pMem->flags = MEM_RowSet; } @@ -789,7 +799,7 @@ void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ sqlite3VdbeMemRelease(pTo); memcpy(pTo, pFrom, sizeof(Mem)); pFrom->flags = MEM_Null; - pFrom->zMalloc = 0; + pFrom->szMalloc = 0; } /* @@ -863,6 +873,7 @@ int sqlite3VdbeMemSetStr( }else if( xDel==SQLITE_DYNAMIC ){ sqlite3VdbeMemRelease(pMem); pMem->zMalloc = pMem->z = (char *)z; + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); }else{ sqlite3VdbeMemRelease(pMem); pMem->z = (char *)z; @@ -1485,7 +1496,7 @@ void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ Mem *aMem = pRec->aMem; sqlite3 *db = aMem[0].db; for(i=0; ipKeyInfo); sqlite3DbFree(db, pRec); From 322f2852f29a2a315252a7f56d50a4723d9e7b46 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 00:43:39 +0000 Subject: [PATCH 46/65] Add the sqlite3VdbeMemClearAndResize() interface to be used in place of sqlite3VdbeMemGrow(). FossilOrigin-Name: 5b9b8987797abf7c68d2c3154f6657be9b8b1c8f --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/vdbe.c | 8 ++++---- src/vdbeInt.h | 1 + src/vdbeapi.c | 2 +- src/vdbeaux.c | 6 +++--- src/vdbemem.c | 35 +++++++++++++++++++++++++++++++---- src/vdbesort.c | 2 +- 8 files changed, 53 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 1ced1cbf05..28c4382ce9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sMem.szMalloc\selement\sto\sthe\sMem\sobject\sand\suse\sit\sto\skeep\strack\sof\nthe\ssize\sof\sthe\sMem.zMalloc\sallocation. -D 2014-09-18T21:25:33.845 +C Add\sthe\ssqlite3VdbeMemClearAndResize()\sinterface\sto\sbe\sused\sin\splace\sof\nsqlite3VdbeMemGrow(). +D 2014-09-19T00:43:39.899 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,14 +288,14 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c fb490f5b1b2ee2f33f60c7dc678c0d0b70f2e0cb +F src/vdbe.c 7bc115e540282b1bfff9b43205cbf6528e6398a6 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 -F src/vdbeInt.h 1ac536d1fa1260d72f81003ff5b283e8f3c40442 -F src/vdbeapi.c e088ed70b6cc42ed68985ab064397ebd452286d6 -F src/vdbeaux.c b3230032238df611aefee5907ea792786362a55d +F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 +F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d +F src/vdbeaux.c ecf0bb835f7c809ba8e22ba7d3a587b7a087ac52 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 3aea3831a981378368ca058cd8fc700b1982772d -F src/vdbesort.c 09efa5e5098d1a159cd21f588eb118e4fe87cfde +F src/vdbemem.c 0678ba6214a810539e51c6d8f263634d405b990f +F src/vdbesort.c 75c66c2fc02d450b67b4816873fba8088feaf12c F src/vdbetrace.c 4f29b04edb0cec3d5fcd9b566d9f0e75c8984362 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983 @@ -1198,7 +1198,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 55879932116d373c95a5f32ec44b53a9c3f4db24 -R 508057a57cef866ce62608d1eb2d9e8e +P 9c09ac353df6041808cace41880f4729ee73f5e1 +R eeadad19cadf3315e345f0babe4222b0 U drh -Z 7d8fd1db974daf115bf085d0714b6de9 +Z fd83cfbfc71d89fd149fcf4e06924224 diff --git a/manifest.uuid b/manifest.uuid index 77cd05df09..a4139a3651 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c09ac353df6041808cace41880f4729ee73f5e1 \ No newline at end of file +5b9b8987797abf7c68d2c3154f6657be9b8b1c8f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 4a63f30af8..25a33a63f7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -209,7 +209,7 @@ static VdbeCursor *allocateCursor( sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } - if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){ + if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pCx, 0, sizeof(VdbeCursor)); pCx->iDb = iDb; @@ -2633,9 +2633,9 @@ case OP_MakeRecord: { /* Make sure the output register has a buffer large enough to store ** the new record. The output register (pOp->p3) is not allowed to ** be one of the input registers (because the following call to - ** sqlite3VdbeMemGrow() could clobber the value before it is used). + ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). */ - if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){ + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ goto no_mem; } zNewRecord = (u8 *)pOut->z; @@ -4339,7 +4339,7 @@ case OP_RowData: { goto too_big; } } - if( sqlite3VdbeMemGrow(pOut, n, 0) ){ + if( sqlite3VdbeMemClearAndResize(pOut, n) ){ goto no_mem; } pOut->n = n; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 138e61d2c2..56b5db7d1a 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -437,6 +437,7 @@ void sqlite3VdbeMemRelease(Mem *p); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); +int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 7d3ae9cb07..dc38132382 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -665,7 +665,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ sqlite3VdbeMemSetNull(pMem); pMem->z = 0; }else{ - sqlite3VdbeMemGrow(pMem, nByte, 0); + sqlite3VdbeMemClearAndResize(pMem, nByte); pMem->flags = MEM_Agg; pMem->u.pDef = p->pFunc; if( pMem->z ){ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f990c40d41..3ce373dffe 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1426,7 +1426,7 @@ int sqlite3VdbeList( pMem->u.i = pOp->p3; /* P3 */ pMem++; - if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */ + if( sqlite3VdbeMemClearAndResize(pMem, 32) ){ /* P4 */ assert( p->db->mallocFailed ); return SQLITE_ERROR; } @@ -1442,7 +1442,7 @@ int sqlite3VdbeList( pMem++; if( p->explain==1 ){ - if( sqlite3VdbeMemGrow(pMem, 4, 0) ){ + if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ assert( p->db->mallocFailed ); return SQLITE_ERROR; } @@ -1453,7 +1453,7 @@ int sqlite3VdbeList( pMem++; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - if( sqlite3VdbeMemGrow(pMem, 500, 0) ){ + if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ assert( p->db->mallocFailed ); return SQLITE_ERROR; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 4ea28f841f..ff9f5b6df5 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -107,7 +107,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ ** blob if bPreserve is true. If bPreserve is false, any prior content ** in pMem->z is discarded. */ -int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ +SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( sqlite3VdbeCheckMemInvariants(pMem) ); assert( (pMem->flags&MEM_RowSet)==0 ); @@ -150,6 +150,33 @@ int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ return SQLITE_OK; } +/* +** Change the pMem->zMalloc allocation to be at least szNew bytes. +** If pMem->zMalloc already meets or exceeds the requested size, this +** routine is a no-op. +** +** Any prior string or blob content in the pMem object may be discarded. +** The pMem->xDel destructor is called, if it exists. +** +** The value of the pMem after this routine returns might be NULL or +** it might retain its prior value, depending on circumstances. The +** caller should make no assumptions about the state of pMem after this +** routine returns, except that pMem->zMalloc is at least the requested +** size and pMem->z==pMem->zMalloc. +** +** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) +** if unable to complete the resizing. +*/ +int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ + if( pMem->szMallocflags & MEM_Dyn)!=0 ){ + return sqlite3VdbeMemGrow(pMem, szNew, 0); + } + pMem->z = pMem->zMalloc; + pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static); +// pMem->flags = MEM_Null; + return SQLITE_OK; +} + /* ** Make the given Mem object MEM_Dyn. In other words, make it so ** that any TEXT or BLOB content is stored in memory obtained from @@ -262,7 +289,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){ + if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ return SQLITE_NOMEM; } @@ -866,7 +893,7 @@ int sqlite3VdbeMemSetStr( if( nByte>iLimit ){ return SQLITE_TOOBIG; } - if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){ + if( sqlite3VdbeMemClearAndResize(pMem, nAlloc) ){ return SQLITE_NOMEM; } memcpy(pMem->z, z, nAlloc); @@ -944,7 +971,7 @@ int sqlite3VdbeMemFromBtree( pMem->n = (int)amt; }else{ pMem->flags = MEM_Null; - if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){ + if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){ if( key ){ rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z); }else{ diff --git a/src/vdbesort.c b/src/vdbesort.c index 2d7bc8a7a4..3e82f6e822 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -2461,7 +2461,7 @@ int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ void *pKey; int nKey; /* Sorter key to copy into pOut */ pKey = vdbeSorterRowkey(pSorter, &nKey); - if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ + if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ return SQLITE_NOMEM; } pOut->n = nKey; From 137fd4fda27c3c0b64f80d8523996559dd20aebe Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 02:01:37 +0000 Subject: [PATCH 47/65] Make sure that the sorting-index pre-filter recognizes that a rowid reference might be sortable. This fixes a performance regression. FossilOrigin-Name: 72727b68cd07969165f1f0943cc7e1a265436653 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 1 + test/orderby1.test | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 28c4382ce9..786c774f55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3VdbeMemClearAndResize()\sinterface\sto\sbe\sused\sin\splace\sof\nsqlite3VdbeMemGrow(). -D 2014-09-19T00:43:39.899 +C Make\ssure\sthat\sthe\ssorting-index\spre-filter\srecognizes\sthat\sa\srowid\sreference\nmight\sbe\ssortable.\s\sThis\sfixes\sa\sperformance\sregression. +D 2014-09-19T02:01:37.043 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -301,7 +301,7 @@ F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c dc276288039fb45ce23c80e4535980f5a152d8ec +F src/where.c 0888567c0e01a41b6001647e333f8ccfd3ae7d36 F src/whereInt.h 124d970450955a6982e174b07c320ae6d62a595c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -739,7 +739,7 @@ F test/notnull.test f8fcf58669ddba79274daa2770d61dfad8274f62 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 -F test/orderby1.test 12426f99518cde45f34215ca6a0ebc0e9bc5c77a +F test/orderby1.test eb246e377612b21a418fbea57047ba8ea88aaa6b F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04 F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99 F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4 @@ -1198,7 +1198,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 9c09ac353df6041808cace41880f4729ee73f5e1 -R eeadad19cadf3315e345f0babe4222b0 +P 5b9b8987797abf7c68d2c3154f6657be9b8b1c8f +R 15204d62056b16fb4766540f7ebb9528 U drh -Z fd83cfbfc71d89fd149fcf4e06924224 +Z d3f0dcf862181fb956350fa4a77ff638 diff --git a/manifest.uuid b/manifest.uuid index a4139a3651..06e5229d32 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b9b8987797abf7c68d2c3154f6657be9b8b1c8f \ No newline at end of file +72727b68cd07969165f1f0943cc7e1a265436653 \ No newline at end of file diff --git a/src/where.c b/src/where.c index c7cb7bb67c..318065d486 100644 --- a/src/where.c +++ b/src/where.c @@ -4560,6 +4560,7 @@ static int indexMightHelpWithOrderBy( Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr); if( pExpr->op!=TK_COLUMN ) return 0; if( pExpr->iTable==iCursor ){ + if( pExpr->iColumn<0 ) return 1; for(jj=0; jjnKeyCol; jj++){ if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1; } diff --git a/test/orderby1.test b/test/orderby1.test index e06c9f19a0..6674e32220 100644 --- a/test/orderby1.test +++ b/test/orderby1.test @@ -481,5 +481,19 @@ do_execsql_test 6.0 { FROM abc; } {hardware hardware hardware} +# Here is a test for a query-planner problem reported on the SQLite +# mailing list on 2014-09-18 by "Merike". Beginning with version 3.8.0, +# a separate sort was being used rather than using the single-column +# index. This was due to an oversight in the indexMightHelpWithOrderby() +# routine in where.c. +# +do_execsql_test 7.0 { + CREATE TABLE t7(a,b); + CREATE INDEX t7a ON t7(a); + CREATE INDEX t7ab ON t7(a,b); + EXPLAIN QUERY PLAN + SELECT * FROM t7 WHERE a=?1 ORDER BY rowid; +} {~/ORDER BY/} + finish_test From 7b5ebcaf26d6640f5b4997732c8c5161feda4c9e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 15:28:33 +0000 Subject: [PATCH 48/65] The OP_Column opcode runs faster and is smaller by manually in-lining the code that persists string values in the output register. FossilOrigin-Name: 36b613ccf0ddb764af90841994da91b7fcaa8f00 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 013d54f55b..611616d0c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3VdbeMemClearAndResize()\sfunction.\s\sFix\sa\ssorting-index\nprefilter\sproblem. -D 2014-09-19T04:42:38.074 +C The\sOP_Column\sopcode\sruns\sfaster\sand\sis\ssmaller\sby\smanually\sin-lining\sthe\ncode\sthat\spersists\sstring\svalues\sin\sthe\soutput\sregister. +D 2014-09-19T15:28:33.728 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 7bc115e540282b1bfff9b43205cbf6528e6398a6 +F src/vdbe.c 9f2a0a2dfa06e99feabd754e9be3a436ac3cf97d F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d @@ -1198,8 +1198,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 9c09ac353df6041808cace41880f4729ee73f5e1 72727b68cd07969165f1f0943cc7e1a265436653 -R a5960c77be61d5e92e67de5776336365 -T +closed 72727b68cd07969165f1f0943cc7e1a265436653 +P 987a7a211913b3949da20e43423af376f72a28ba +R 03eb020eed7bf3a8527e5a4e8f2d486b U drh -Z 88c7b85ca090541e4ecff878bb673522 +Z 0d995c472ae8295ead3b2ebd0d73fc53 diff --git a/manifest.uuid b/manifest.uuid index 6dc6c4d043..f8720261f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -987a7a211913b3949da20e43423af376f72a28ba \ No newline at end of file +36b613ccf0ddb764af90841994da91b7fcaa8f00 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 25a33a63f7..0baacef4c0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2482,7 +2482,21 @@ case OP_Column: { pDest->enc = encoding; op_column_out: - Deephemeralize(pDest); + /* If the column value is an ephemeral string, go ahead and persist + ** that string in case the cursor moves before the column value is + ** used. The following code does the equivalent of Deephemeralize() + ** but does it faster. */ + if( (pDest->flags & MEM_Ephem)!=0 && pDest->z ){ + u16 f = pDest->flags & (MEM_Str|MEM_Blob); + assert( f!=0 ); + zData = (const u8*)pDest->z; + len = pDest->n; + if( sqlite3VdbeMemClearAndResize(pDest, len+2) ) goto no_mem; + memcpy(pDest->z, zData, len); + pDest->z[len] = 0; + pDest->z[len+1] = 0; + pDest->flags = f|MEM_Term; + } op_column_error: UPDATE_MAX_BLOBSIZE(pDest); REGISTER_TRACE(pOp->p3, pDest); From 7abda856074ec8fecc28ca7a5fb2fc630b403e23 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 16:02:06 +0000 Subject: [PATCH 49/65] Updates to comments. No code changes. FossilOrigin-Name: 9b42c3da6b2593a10b8fe4b2fcc3d650132625c1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 12 +++--------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 611616d0c2..c87b875a6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sOP_Column\sopcode\sruns\sfaster\sand\sis\ssmaller\sby\smanually\sin-lining\sthe\ncode\sthat\spersists\sstring\svalues\sin\sthe\soutput\sregister. -D 2014-09-19T15:28:33.728 +C Updates\sto\scomments.\s\sNo\scode\schanges. +D 2014-09-19T16:02:06.389 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -292,7 +292,7 @@ F src/vdbe.c 9f2a0a2dfa06e99feabd754e9be3a436ac3cf97d F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d -F src/vdbeaux.c ecf0bb835f7c809ba8e22ba7d3a587b7a087ac52 +F src/vdbeaux.c 498b42510679767ea6c893c8c51a8fd935d7ab2d F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c 5cd963730414a1a6ba53b8b340eba3f46ec2cb1d F src/vdbesort.c 75c66c2fc02d450b67b4816873fba8088feaf12c @@ -1198,7 +1198,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 987a7a211913b3949da20e43423af376f72a28ba -R 03eb020eed7bf3a8527e5a4e8f2d486b +P 36b613ccf0ddb764af90841994da91b7fcaa8f00 +R 080b311a7df7cfe0ac5886dd9047451e U drh -Z 0d995c472ae8295ead3b2ebd0d73fc53 +Z bac819561e5ec88b9538e526b2bc8493 diff --git a/manifest.uuid b/manifest.uuid index f8720261f1..66235033a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36b613ccf0ddb764af90841994da91b7fcaa8f00 \ No newline at end of file +9b42c3da6b2593a10b8fe4b2fcc3d650132625c1 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 3ce373dffe..f4d50406b9 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -10,9 +10,7 @@ ** ************************************************************************* ** This file contains code used for creating, destroying, and populating -** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior -** to version 2.8.7, all this code was combined into the vdbe.c source file. -** But that file was getting too big so this subroutines were split out. +** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -1606,7 +1604,7 @@ void sqlite3VdbeRewind(Vdbe *p){ /* ** Prepare a virtual machine for execution for the first time after ** creating the virtual machine. This involves things such -** as allocating stack space and initializing the program counter. +** as allocating registers and initializing the program counter. ** After the VDBE has be prepped, it can be executed by one or more ** calls to sqlite3VdbeExec(). ** @@ -1818,11 +1816,7 @@ static void closeAllCursors(Vdbe *p){ } /* -** Clean up the VM after execution. -** -** This routine will automatically close any cursors, lists, and/or -** sorters that were left open. It also deletes the values of -** variables in the aVar[] array. +** Clean up the VM after a single run. */ static void Cleanup(Vdbe *p){ sqlite3 *db = p->db; From 069c23c947cd5b5e85b6d9bf10d6291547fbda4f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 16:13:12 +0000 Subject: [PATCH 50/65] Small size reduction and performance increase for releaseMemArray(). FossilOrigin-Name: 24cd32d681df58f687b2afbe4b13d579e3efdd4b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c87b875a6b..ddd7321ef0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\scomments.\s\sNo\scode\schanges. -D 2014-09-19T16:02:06.389 +C Small\ssize\sreduction\sand\sperformance\sincrease\sfor\sreleaseMemArray(). +D 2014-09-19T16:13:12.685 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -292,7 +292,7 @@ F src/vdbe.c 9f2a0a2dfa06e99feabd754e9be3a436ac3cf97d F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d -F src/vdbeaux.c 498b42510679767ea6c893c8c51a8fd935d7ab2d +F src/vdbeaux.c a05adc3c96abdaf3db14768ddd63132fc9678060 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c 5cd963730414a1a6ba53b8b340eba3f46ec2cb1d F src/vdbesort.c 75c66c2fc02d450b67b4816873fba8088feaf12c @@ -1198,7 +1198,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 36b613ccf0ddb764af90841994da91b7fcaa8f00 -R 080b311a7df7cfe0ac5886dd9047451e +P 9b42c3da6b2593a10b8fe4b2fcc3d650132625c1 +R 351b243201f0eb22d3adcd68e13fd4a5 U drh -Z bac819561e5ec88b9538e526b2bc8493 +Z 9538899cfe34e917b2f35980fa39505f diff --git a/manifest.uuid b/manifest.uuid index 66235033a3..5c4c41d72c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b42c3da6b2593a10b8fe4b2fcc3d650132625c1 \ No newline at end of file +24cd32d681df58f687b2afbe4b13d579e3efdd4b \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f4d50406b9..87b14a6d87 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1224,16 +1224,16 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ */ static void releaseMemArray(Mem *p, int N){ if( p && N ){ - Mem *pEnd; + Mem *pEnd = &p[N]; sqlite3 *db = p->db; u8 malloc_failed = db->mallocFailed; if( db->pnBytesFreed ){ - for(pEnd=&p[N]; pszMalloc ) sqlite3DbFree(db, p->zMalloc); - } + }while( (++p)flags = MEM_Undefined; - } + }while( (++p)mallocFailed = malloc_failed; } } From 0c8f760ab35068d339edc4a4b9aee070c0198b47 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 16:56:45 +0000 Subject: [PATCH 51/65] Remove a local variable from the OP_Column implementation, resulting in a modest size reduction and a performance increase. FossilOrigin-Name: 6199760d1340858d97c845177986b783da915d9e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 23 +++++++++++------------ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index ddd7321ef0..bb272d2568 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\sincrease\sfor\sreleaseMemArray(). -D 2014-09-19T16:13:12.685 +C Remove\sa\slocal\svariable\sfrom\sthe\sOP_Column\simplementation,\sresulting\sin\sa\nmodest\ssize\sreduction\sand\sa\sperformance\sincrease. +D 2014-09-19T16:56:45.748 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 9f2a0a2dfa06e99feabd754e9be3a436ac3cf97d +F src/vdbe.c c90b7ebe856beb75077cf4486efc1863de219f34 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d @@ -1198,7 +1198,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 9b42c3da6b2593a10b8fe4b2fcc3d650132625c1 -R 351b243201f0eb22d3adcd68e13fd4a5 +P 24cd32d681df58f687b2afbe4b13d579e3efdd4b +R dfacf0845df6af56f07b0acf2e71dc1f U drh -Z 9538899cfe34e917b2f35980fa39505f +Z 845eafc57b4e53556b2c7ee6a79ebdad diff --git a/manifest.uuid b/manifest.uuid index 5c4c41d72c..67c66e8f0f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24cd32d681df58f687b2afbe4b13d579e3efdd4b \ No newline at end of file +6199760d1340858d97c845177986b783da915d9e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0baacef4c0..9b679c534b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2257,7 +2257,6 @@ case OP_Column: { int p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ BtCursor *pCrsr; /* The BTree cursor */ - u32 *aType; /* aType[i] holds the numeric type of the i-th column */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ @@ -2270,6 +2269,7 @@ case OP_Column: { u32 szField; /* Number of bytes in the content of a field */ u32 avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ + u16 fx; /* pDest->flags value */ Mem *pReg; /* PseudoTable input register */ p2 = pOp->p2; @@ -2280,8 +2280,7 @@ case OP_Column: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( p2nField ); - aType = pC->aType; - aOffset = aType + pC->nField; + aOffset = pC->aType + pC->nField; #ifndef SQLITE_OMIT_VIRTUALTABLE assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ #endif @@ -2362,7 +2361,7 @@ case OP_Column: { } /* Make sure at least the first p2+1 entries of the header have been - ** parsed and valid information is in aOffset[] and aType[]. + ** parsed and valid information is in aOffset[] and pC->aType[]. */ if( pC->nHdrParsed<=p2 ){ /* If there is more header available for parsing in the record, try @@ -2382,7 +2381,7 @@ case OP_Column: { zData = pC->aRow; } - /* Fill in aType[i] and aOffset[i] values through the p2-th field. */ + /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ i = pC->nHdrParsed; offset = aOffset[i]; zHdr = zData + pC->iHdrOffset; @@ -2395,7 +2394,7 @@ case OP_Column: { }else{ zHdr += sqlite3GetVarint32(zHdr, &t); } - aType[i] = t; + pC->aType[i] = t; szField = sqlite3VdbeSerialTypeLen(t); offset += szField; if( offsetaType[p2] are ** all valid. */ assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); assert( sqlite3VdbeCheckMemInvariants(pDest) ); if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest); + t = pC->aType[p2]; if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the desired content fits on the original ** page - where the content is not on an overflow page */ - sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); + sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest); }else{ /* This branch happens only when content is on overflow pages */ - t = aType[p2]; if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) || (len = sqlite3VdbeSerialTypeLen(t))==0 @@ -2487,15 +2486,15 @@ op_column_out: ** used. The following code does the equivalent of Deephemeralize() ** but does it faster. */ if( (pDest->flags & MEM_Ephem)!=0 && pDest->z ){ - u16 f = pDest->flags & (MEM_Str|MEM_Blob); - assert( f!=0 ); + fx = pDest->flags & (MEM_Str|MEM_Blob); + assert( fx!=0 ); zData = (const u8*)pDest->z; len = pDest->n; if( sqlite3VdbeMemClearAndResize(pDest, len+2) ) goto no_mem; memcpy(pDest->z, zData, len); pDest->z[len] = 0; pDest->z[len+1] = 0; - pDest->flags = f|MEM_Term; + pDest->flags = fx|MEM_Term; } op_column_error: UPDATE_MAX_BLOBSIZE(pDest); From 142341cd2344c8c97e34d20db51c6e266c652e36 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 19:00:48 +0000 Subject: [PATCH 52/65] Make the "nolock" VFS on unix a version-3 VFS so that the sorter can use memory-mapped I/O. FossilOrigin-Name: 3db78d6100a1ecf58c18eec3abefa7d1250c649c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index bb272d2568..6127e2a58d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\slocal\svariable\sfrom\sthe\sOP_Column\simplementation,\sresulting\sin\sa\nmodest\ssize\sreduction\sand\sa\sperformance\sincrease. -D 2014-09-19T16:56:45.748 +C Make\sthe\s"nolock"\sVFS\son\sunix\sa\sversion-3\sVFS\sso\sthat\sthe\ssorter\scan\nuse\smemory-mapped\sI/O. +D 2014-09-19T19:00:48.687 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -211,7 +211,7 @@ F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c addd023b26c623fec4dedc110fc4370a65b4768c +F src/os_unix.c 9096a1b1449182e67e759f59994eee04113bc587 F src/os_win.c 0a4042ef35f322e86fa01f6c8884c5e645b911e7 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/pager.c caab007743821d96752597c9cfd7351654697b06 @@ -1198,7 +1198,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 24cd32d681df58f687b2afbe4b13d579e3efdd4b -R dfacf0845df6af56f07b0acf2e71dc1f +P 6199760d1340858d97c845177986b783da915d9e +R 747bc9b4978b6e3fd1fc3d52243dfaf2 U drh -Z 845eafc57b4e53556b2c7ee6a79ebdad +Z 26fea32b6bd594b310d5a7de197ed86f diff --git a/manifest.uuid b/manifest.uuid index 67c66e8f0f..146b5e3eb7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6199760d1340858d97c845177986b783da915d9e \ No newline at end of file +3db78d6100a1ecf58c18eec3abefa7d1250c649c \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 5e820260a4..fcd9e72d06 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4997,7 +4997,7 @@ IOMETHODS( IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ + 3, /* shared memory is disabled */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ nolockUnlock, /* xUnlock method */ From d74a90eab8903192e29fc56851eeee0f0410904f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 19:43:20 +0000 Subject: [PATCH 53/65] Do not attempt to extend the temp file if VFS version 3 is not supported and hence memory mapped I/O is unavailable. FossilOrigin-Name: 3ab20ba14f0204efeec62c7dbb87cb3f60e2497f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbesort.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6127e2a58d..4f686333df 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\s"nolock"\sVFS\son\sunix\sa\sversion-3\sVFS\sso\sthat\sthe\ssorter\scan\nuse\smemory-mapped\sI/O. -D 2014-09-19T19:00:48.687 +C Do\snot\sattempt\sto\sextend\sthe\stemp\sfile\sif\sVFS\sversion\s3\sis\snot\ssupported\sand\nhence\smemory\smapped\sI/O\sis\sunavailable. +D 2014-09-19T19:43:20.458 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -295,7 +295,7 @@ F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d F src/vdbeaux.c a05adc3c96abdaf3db14768ddd63132fc9678060 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 F src/vdbemem.c 5cd963730414a1a6ba53b8b340eba3f46ec2cb1d -F src/vdbesort.c 75c66c2fc02d450b67b4816873fba8088feaf12c +F src/vdbesort.c 5c1bacf90578d22b630fbf6ed98ccf60d83435ef F src/vdbetrace.c 4f29b04edb0cec3d5fcd9b566d9f0e75c8984362 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f F src/wal.c 10e7de7ce90865a68153f001a61f1d985cd17983 @@ -1198,7 +1198,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 6199760d1340858d97c845177986b783da915d9e -R 747bc9b4978b6e3fd1fc3d52243dfaf2 +P 3db78d6100a1ecf58c18eec3abefa7d1250c649c +R 818146e215cbcd83bc222da6a20cc822 U drh -Z 26fea32b6bd594b310d5a7de197ed86f +Z 7ba13d68a7d8baeb2d8a716a6d033daa diff --git a/manifest.uuid b/manifest.uuid index 146b5e3eb7..ab36f8e2a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3db78d6100a1ecf58c18eec3abefa7d1250c649c \ No newline at end of file +3ab20ba14f0204efeec62c7dbb87cb3f60e2497f \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index 3e82f6e822..d9679caa06 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1124,9 +1124,9 @@ void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ ** the specific VFS implementation. */ static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ - if( nByte<=(i64)(db->nMaxSorterMmap) ){ + if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){ int rc = sqlite3OsTruncate(pFd, nByte); - if( rc==SQLITE_OK && pFd->pMethods->iVersion>=3 ){ + if( rc==SQLITE_OK ){ void *p = 0; sqlite3OsFetch(pFd, 0, (int)nByte, &p); sqlite3OsUnfetch(pFd, 0, p); From 4583c37ca0361ce9bdc19dd0bae8998f5b576466 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 20:13:25 +0000 Subject: [PATCH 54/65] Fix the affinity on inserts into the ANALYZE tables. Change the affinity characters to be upper case, to make the P5 parameter of comparison operators easier to read. FossilOrigin-Name: 3f3ca76aea38d566a574f4403b375bdac32854ed --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/analyze.c | 6 ++++-- src/insert.c | 22 +++++++++++----------- src/sqliteInt.h | 20 ++++++++++---------- 5 files changed, 34 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 4f686333df..3bf4c484b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sto\sextend\sthe\stemp\sfile\sif\sVFS\sversion\s3\sis\snot\ssupported\sand\nhence\smemory\smapped\sI/O\sis\sunavailable. -D 2014-09-19T19:43:20.458 +C Fix\sthe\saffinity\son\sinserts\sinto\sthe\sANALYZE\stables.\s\sChange\sthe\saffinity\ncharacters\sto\sbe\supper\scase,\sto\smake\sthe\sP5\sparameter\sof\scomparison\soperators\neasier\sto\sread. +D 2014-09-19T20:13:25.422 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb -F src/analyze.c 79383a54fee3b7f1fb03dd4c8c8115583f506de5 +F src/analyze.c 6290a109be876daaa242cd7216f97240f5401776 F src/attach.c f4e94df2d1826feda65eb0939f7f6f5f923a0ad9 F src/auth.c d8abcde53426275dab6243b441256fcd8ccbebb2 F src/backup.c a31809c65623cc41849b94d368917f8bb66e6a7e @@ -188,7 +188,7 @@ F src/global.c 5110fa12e09729b84eee0191c984ec4008e21937 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 0b073fade178d9dbd990bbb32b4438e50b884a06 +F src/insert.c 5b9243a33726008cc4132897d2be371db12a13be F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 @@ -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 9bb8f655b076e1b9ed7cfe0b8c181e758d937369 +F src/sqliteInt.h 686e6a49ebcea813eafa24752d19751ffa6a1b93 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb @@ -1198,7 +1198,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 3db78d6100a1ecf58c18eec3abefa7d1250c649c -R 818146e215cbcd83bc222da6a20cc822 +P 3ab20ba14f0204efeec62c7dbb87cb3f60e2497f +R 6403cad332b96b991c6e79d4338c8e0a U drh -Z 7ba13d68a7d8baeb2d8a716a6d033daa +Z a6ee4447c2926dae75a9d9931c4a5376 diff --git a/manifest.uuid b/manifest.uuid index ab36f8e2a0..5b0f66cb3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ab20ba14f0204efeec62c7dbb87cb3f60e2497f \ No newline at end of file +3f3ca76aea38d566a574f4403b375bdac32854ed \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index d5a11a3ed6..aec1f021ea 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1201,7 +1201,8 @@ static void analyzeOneTable( /* Add the entry to the stat1 table. */ callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); @@ -1264,7 +1265,8 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); + assert( "BBB"[0]==SQLITE_AFF_TEXT ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); diff --git a/src/insert.c b/src/insert.c index 6a3ab8edae..a5c3f3e92d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -56,13 +56,13 @@ void sqlite3OpenTable( ** ** Character Column affinity ** ------------------------------ -** 'a' TEXT -** 'b' NONE -** 'c' NUMERIC -** 'd' INTEGER -** 'e' REAL +** 'A' NONE +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'F' REAL ** -** An extra 'd' is appended to the end of the string to cover the +** An extra 'D' is appended to the end of the string to cover the ** rowid that appears as the last column in every index. ** ** Memory for the buffer containing the column index affinity string @@ -111,11 +111,11 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ ** ** Character Column affinity ** ------------------------------ -** 'a' TEXT -** 'b' NONE -** 'c' NUMERIC -** 'd' INTEGER -** 'e' REAL +** 'A' NONE +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'E' REAL */ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ int i; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ea8ad4573f..92efd9c087 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1422,18 +1422,18 @@ struct CollSeq { ** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve ** the speed a little by numbering the values consecutively. ** -** But rather than start with 0 or 1, we begin with 'a'. That way, +** But rather than start with 0 or 1, we begin with 'A'. That way, ** when multiple affinity types are concatenated into a string and ** used as the P4 operand, they will be more readable. ** ** Note also that the numeric types are grouped together so that testing ** for a numeric type is a single comparison. And the NONE type is first. */ -#define SQLITE_AFF_NONE 'a' -#define SQLITE_AFF_TEXT 'b' -#define SQLITE_AFF_NUMERIC 'c' -#define SQLITE_AFF_INTEGER 'd' -#define SQLITE_AFF_REAL 'e' +#define SQLITE_AFF_NONE 'A' +#define SQLITE_AFF_TEXT 'B' +#define SQLITE_AFF_NUMERIC 'C' +#define SQLITE_AFF_INTEGER 'D' +#define SQLITE_AFF_REAL 'E' #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) @@ -1441,7 +1441,7 @@ struct CollSeq { ** The SQLITE_AFF_MASK values masks off the significant bits of an ** affinity value. */ -#define SQLITE_AFF_MASK 0x67 +#define SQLITE_AFF_MASK 0x47 /* ** Additional bit values that can be ORed with an affinity without @@ -1452,10 +1452,10 @@ struct CollSeq { ** operator is NULL. It is added to certain comparison operators to ** prove that the operands are always NOT NULL. */ -#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */ -#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */ +#define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */ +#define SQLITE_STOREP2 0x20 /* Store result in reg[P2] rather than jump */ #define SQLITE_NULLEQ 0x80 /* NULL=NULL */ -#define SQLITE_NOTNULL 0x88 /* Assert that operands are never NULL */ +#define SQLITE_NOTNULL 0x90 /* Assert that operands are never NULL */ /* ** An object of this type is created for each virtual table present in From 11a6eee8e1a3f74fb319ae69620d3c53658268b3 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 22:01:54 +0000 Subject: [PATCH 55/65] Tighten the conditions under which applyNumericAffinity() be called and add assert() statements to prove that it is never called otherwise. FossilOrigin-Name: e996ca32cb643c558b616c0dd872f3351b6aa3ef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 3bf4c484b9..e2e61762cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\saffinity\son\sinserts\sinto\sthe\sANALYZE\stables.\s\sChange\sthe\saffinity\ncharacters\sto\sbe\supper\scase,\sto\smake\sthe\sP5\sparameter\sof\scomparison\soperators\neasier\sto\sread. -D 2014-09-19T20:13:25.422 +C Tighten\sthe\sconditions\sunder\swhich\sapplyNumericAffinity()\sbe\scalled\sand\sadd\nassert()\sstatements\sto\sprove\sthat\sit\sis\snever\scalled\sotherwise. +D 2014-09-19T22:01:54.366 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c c90b7ebe856beb75077cf4486efc1863de219f34 +F src/vdbe.c 16efd1ae26d877827cd6669f5f19afd8d8903d08 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d @@ -1198,7 +1198,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 3ab20ba14f0204efeec62c7dbb87cb3f60e2497f -R 6403cad332b96b991c6e79d4338c8e0a +P 3f3ca76aea38d566a574f4403b375bdac32854ed +R fc5d306f71c9e96ead7521f7177e02ff U drh -Z a6ee4447c2926dae75a9d9931c4a5376 +Z cb569a0dfcbf7ed8e3897eb9a80bb15e diff --git a/manifest.uuid b/manifest.uuid index 5b0f66cb3c..3fc1bf7213 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3f3ca76aea38d566a574f4403b375bdac32854ed \ No newline at end of file +e996ca32cb643c558b616c0dd872f3351b6aa3ef \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 9b679c534b..136b7abae1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -242,8 +242,7 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ double rValue; i64 iValue; u8 enc = pRec->enc; - if( (pRec->flags&MEM_Str)==0 ) return; - if( (pRec->flags&(MEM_Int|MEM_Real))!=0 ) return; + assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ pRec->u.i = iValue; @@ -283,7 +282,7 @@ static void applyAffinity( || affinity==SQLITE_AFF_NUMERIC ); if( (pRec->flags & MEM_Int)==0 ){ if( (pRec->flags & MEM_Real)==0 ){ - applyNumericAffinity(pRec,1); + if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); }else{ sqlite3VdbeIntegerAffinity(pRec); } @@ -3558,7 +3557,7 @@ case OP_SeekGT: { /* jump, in3 */ ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so convert it. */ pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & (MEM_Int|MEM_Real))==0 ){ + if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3, 0); } iKey = sqlite3VdbeIntValue(pIn3); From 1eda9f7d8702b8a81023e43ce153938f69dd7f62 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 22:30:49 +0000 Subject: [PATCH 56/65] Recognize the invariant that a Mem object cannot be MEM_Dyn and have a non-zero szMalloc at the same time. Enforce this with assert()s and exploit it in the sqlite3VdbeMemClearAndResize() routine for a performance increase. FossilOrigin-Name: 3b21cf2b284048da4b728a5d6ec89e5c330144d4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 13 ++++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e2e61762cf..6625f6c19a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tighten\sthe\sconditions\sunder\swhich\sapplyNumericAffinity()\sbe\scalled\sand\sadd\nassert()\sstatements\sto\sprove\sthat\sit\sis\snever\scalled\sotherwise. -D 2014-09-19T22:01:54.366 +C Recognize\sthe\sinvariant\sthat\sa\sMem\sobject\scannot\sbe\sMEM_Dyn\sand\shave\s\na\snon-zero\sszMalloc\sat\sthe\ssame\stime.\s\sEnforce\sthis\swith\sassert()s\sand\nexploit\sit\sin\sthe\ssqlite3VdbeMemClearAndResize()\sroutine\sfor\sa\sperformance\nincrease. +D 2014-09-19T22:30:49.809 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -294,7 +294,7 @@ F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d F src/vdbeaux.c a05adc3c96abdaf3db14768ddd63132fc9678060 F src/vdbeblob.c 848238dc73e93e48432991bb5651bf87d865eca4 -F src/vdbemem.c 5cd963730414a1a6ba53b8b340eba3f46ec2cb1d +F src/vdbemem.c 1e105dacf5190fc85a8ec2107c0dcc1884e75099 F src/vdbesort.c 5c1bacf90578d22b630fbf6ed98ccf60d83435ef F src/vdbetrace.c 4f29b04edb0cec3d5fcd9b566d9f0e75c8984362 F src/vtab.c 019dbfd0406a7447c990e1f7bd1dfcdb8895697f @@ -1198,7 +1198,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 3f3ca76aea38d566a574f4403b375bdac32854ed -R fc5d306f71c9e96ead7521f7177e02ff +P e996ca32cb643c558b616c0dd872f3351b6aa3ef +R 5148a059197bc43e5fc9e398f77834ac U drh -Z cb569a0dfcbf7ed8e3897eb9a80bb15e +Z 24b5c2935cab55558784e01172e53731 diff --git a/manifest.uuid b/manifest.uuid index 3fc1bf7213..d94cacb1fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e996ca32cb643c558b616c0dd872f3351b6aa3ef \ No newline at end of file +3b21cf2b284048da4b728a5d6ec89e5c330144d4 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 10c91dfd75..36db80fa18 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -31,6 +31,9 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ */ assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 ); + /* MEM_Dyn may only be set if Mem.szMalloc==0 */ + assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); + /* Cannot be both MEM_Int and MEM_Real at the same time */ assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); @@ -164,19 +167,19 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ ** if unable to complete the resizing. */ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ - if( pMem->szMallocflags & MEM_Dyn)!=0 ){ + assert( szNew>=0 ); + if( pMem->szMallocflags & MEM_Dyn)==0 ); pMem->z = pMem->zMalloc; pMem->flags &= (MEM_Null|MEM_Int|MEM_Real); return SQLITE_OK; } /* -** Make the given Mem object MEM_Dyn. In other words, make it so -** that any TEXT or BLOB content is stored in memory obtained from -** malloc(). In this way, we know that the memory is safe to be -** overwritten or altered. +** Change pMem so that its MEM_Str or MEM_Blob value is stored in +** MEM.zMalloc, where it can be safely written. ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ From e7a3466458a175a88fa82c64c7a432825622c1d8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Sep 2014 22:44:20 +0000 Subject: [PATCH 57/65] Simplify two conditionals and add testcase() macros to the affinity transform logic in the comparison operators. FossilOrigin-Name: 544664cadfb4e504bc0b321c865d1ecb8a831e20 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 8 ++++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6625f6c19a..fd932fa1b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Recognize\sthe\sinvariant\sthat\sa\sMem\sobject\scannot\sbe\sMEM_Dyn\sand\shave\s\na\snon-zero\sszMalloc\sat\sthe\ssame\stime.\s\sEnforce\sthis\swith\sassert()s\sand\nexploit\sit\sin\sthe\ssqlite3VdbeMemClearAndResize()\sroutine\sfor\sa\sperformance\nincrease. -D 2014-09-19T22:30:49.809 +C Simplify\stwo\sconditionals\sand\sadd\stestcase()\smacros\sto\sthe\saffinity\stransform\nlogic\sin\sthe\scomparison\soperators. +D 2014-09-19T22:44:20.033 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -288,7 +288,7 @@ F src/update.c 729f6f18fc27740591d085e1172cebe311144bf0 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 4006c01772bd8d8ac4306d523bbcee41d3e392d8 F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a -F src/vdbe.c 16efd1ae26d877827cd6669f5f19afd8d8903d08 +F src/vdbe.c de1af1795bebdad20c23e82bafa2f531e9893198 F src/vdbe.h 09f5b4e3719fa454f252322b1cdab5cf1f361327 F src/vdbeInt.h f177bed1ec8d4eb5c7089f012aeb95f374745735 F src/vdbeapi.c e9e33b59834e3edc8790209765e069874c269d9d @@ -1198,7 +1198,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 e996ca32cb643c558b616c0dd872f3351b6aa3ef -R 5148a059197bc43e5fc9e398f77834ac +P 3b21cf2b284048da4b728a5d6ec89e5c330144d4 +R c321e5b6443015b26d22f3eade4b771c U drh -Z 24b5c2935cab55558784e01172e53731 +Z b0d83e95571a3002a17dc014110d23f5 diff --git a/manifest.uuid b/manifest.uuid index d94cacb1fd..aee58dcbcb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b21cf2b284048da4b728a5d6ec89e5c330144d4 \ No newline at end of file +544664cadfb4e504bc0b321c865d1ecb8a831e20 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 136b7abae1..26ca72b9f4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1900,17 +1900,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ /* Neither operand is NULL. Do a comparison. */ affinity = pOp->p5 & SQLITE_AFF_MASK; if( affinity>=SQLITE_AFF_NUMERIC ){ - if( (pIn1->flags & (MEM_Int|MEM_Real))==0 && (pIn1->flags&MEM_Str)!=0 ){ + if( (pIn1->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); } - if( (pIn3->flags & (MEM_Int|MEM_Real))==0 && (pIn3->flags&MEM_Str)!=0 ){ + if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3,0); } }else if( affinity==SQLITE_AFF_TEXT ){ if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){ + testcase( pIn1->flags & MEM_Int ); + testcase( pIn1->flags & MEM_Real ); sqlite3VdbeMemStringify(pIn1, encoding, 1); } if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){ + testcase( pIn3->flags & MEM_Int ); + testcase( pIn3->flags & MEM_Real ); sqlite3VdbeMemStringify(pIn3, encoding, 1); } } From 33ac4c8bf5de82ab0e496b1da86fc1f1d1ba8f3f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 20 Sep 2014 00:02:23 +0000 Subject: [PATCH 58/65] Revise macro usage in 'sqliteInt.h'. FossilOrigin-Name: 35db3e2f350ca2bc6bb9e1a647aec7f93bfb7065 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/printf.c | 2 +- src/sqliteInt.h | 18 +++++++++--------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index fd932fa1b7..9125f11713 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\stwo\sconditionals\sand\sadd\stestcase()\smacros\sto\sthe\saffinity\stransform\nlogic\sin\sthe\scomparison\soperators. -D 2014-09-19T22:44:20.033 +C Revise\smacro\susage\sin\s'sqliteInt.h'. +D 2014-09-20T00:02:23.616 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -222,7 +222,7 @@ F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196 -F src/printf.c 19e3e81addf593195369ec8d487ed063ad3170bb +F src/printf.c 901a2b924f10db42b7c32936eda80feb3a769aca F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e @@ -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 686e6a49ebcea813eafa24752d19751ffa6a1b93 +F src/sqliteInt.h 6fd801cac974d310949ddefd6a6c6982c9778f3f F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb @@ -1198,7 +1198,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 3b21cf2b284048da4b728a5d6ec89e5c330144d4 -R c321e5b6443015b26d22f3eade4b771c -U drh -Z b0d83e95571a3002a17dc014110d23f5 +P 544664cadfb4e504bc0b321c865d1ecb8a831e20 +R 5186d6949cf27e738e34796d88aa31e5 +T *branch * sqliteIntMacros +T *sym-sqliteIntMacros * +T -sym-trunk * +U mistachkin +Z 51ca01ef3bf4ffdaf2fde2b29bc4c756 diff --git a/manifest.uuid b/manifest.uuid index aee58dcbcb..4d3ec94e76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -544664cadfb4e504bc0b321c865d1ecb8a831e20 \ No newline at end of file +35db3e2f350ca2bc6bb9e1a647aec7f93bfb7065 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 03e39085b9..9173cf7332 100644 --- a/src/printf.c +++ b/src/printf.c @@ -21,7 +21,7 @@ ** the glibc version so the glibc version is definitely preferred. */ #if !defined(HAVE_STRCHRNUL) -# if defined(__linux__) && defined(_GNU_SOURCE) +# if defined(_GNU_SOURCE) # define HAVE_STRCHRNUL 1 # else # define HAVE_STRCHRNUL 0 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 92efd9c087..75cfeefa0d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -47,6 +47,15 @@ # define _LARGEFILE_SOURCE 1 #endif +/* Needed for various definitions... */ +#if defined(__GNUC__) && !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif + +#if defined(__OpenBSD__) && !defined(_BSD_SOURCE) +# define _BSD_SOURCE +#endif + /* ** For MinGW, check to see if we can include the header file containing its ** version information, among other things. Normally, this internal MinGW @@ -104,15 +113,6 @@ #pragma warn -spa /* Suspicious pointer arithmetic */ #endif -/* Needed for various definitions... */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#if defined(__OpenBSD__) && !defined(_BSD_SOURCE) -# define _BSD_SOURCE -#endif - /* ** Include standard header files as necessary */ From 4e7a479597ea919eca9fa82e304bd424dfd9eccf Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Sep 2014 00:29:20 +0000 Subject: [PATCH 59/65] Only enable HAVE_STRCHRNUL by default on linux, as that is the only place it appears to work by default. FossilOrigin-Name: 0fac2c045f47c7735af4eb68ced81d8b43622a1f --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/printf.c | 2 +- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 9125f11713..aa9b7846e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\smacro\susage\sin\s'sqliteInt.h'. -D 2014-09-20T00:02:23.616 +C Only\senable\sHAVE_STRCHRNUL\sby\sdefault\son\slinux,\sas\sthat\sis\sthe\sonly\splace\nit\sappears\sto\swork\sby\sdefault. +D 2014-09-20T00:29:20.392 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -222,7 +222,7 @@ F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa F src/pragma.c 3f3e959390a10c0131676f0e307acce372777e0f F src/prepare.c 6ef0cf2f9274982988ed6b7cab1be23147e94196 -F src/printf.c 901a2b924f10db42b7c32936eda80feb3a769aca +F src/printf.c 3a47f526b173813d9a7f4e7044007771ba68cde1 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e @@ -1198,10 +1198,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 544664cadfb4e504bc0b321c865d1ecb8a831e20 -R 5186d6949cf27e738e34796d88aa31e5 -T *branch * sqliteIntMacros -T *sym-sqliteIntMacros * -T -sym-trunk * -U mistachkin -Z 51ca01ef3bf4ffdaf2fde2b29bc4c756 +P 35db3e2f350ca2bc6bb9e1a647aec7f93bfb7065 +R 8acbfeff4e0806bab5948d89d293bcf4 +U drh +Z 6fc488f20a05aa47a5cf4ff95476cc98 diff --git a/manifest.uuid b/manifest.uuid index 4d3ec94e76..da30674aba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35db3e2f350ca2bc6bb9e1a647aec7f93bfb7065 \ No newline at end of file +0fac2c045f47c7735af4eb68ced81d8b43622a1f \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 9173cf7332..6d4b1b4ac7 100644 --- a/src/printf.c +++ b/src/printf.c @@ -21,7 +21,7 @@ ** the glibc version so the glibc version is definitely preferred. */ #if !defined(HAVE_STRCHRNUL) -# if defined(_GNU_SOURCE) +# if defined(linux) # define HAVE_STRCHRNUL 1 # else # define HAVE_STRCHRNUL 0 From abd4c72357435db2f4a46d0acf8455ba2ed98fcc Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Sep 2014 18:18:33 +0000 Subject: [PATCH 60/65] Enable SELECT query planning tracing when compiled with SQLITE_ENABLE_SELECTTRACE and either SQLITE_DEBUG or SQLITE_TEST. FossilOrigin-Name: cbe0cf9ddf46f0a678c85d49bfa74e3b7712e1a1 --- manifest | 19 +++++++++---------- manifest.uuid | 2 +- src/parse.y | 26 +++++++++++++++++++++++++- src/select.c | 13 +++++++++++++ src/shell.c | 9 +++++++++ src/sqliteInt.h | 17 +++++++++++++++++ 6 files changed, 74 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 34532191e9..fd7616c7ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\susage\sof\sthe\s_GNU_SOURCE\sand\s_BSD_SOURCE\smacros\sin\sthe\smain\ninternal\sheader\sfile,\ssqliteInt.h.\s\sSet\sHAVE_STRCHRNUL\sto\s1\sby\sdefault\son\nLinux\sonly. -D 2014-09-20T00:35:05.099 +C Enable\sSELECT\squery\splanning\stracing\swhen\scompiled\swith\s\nSQLITE_ENABLE_SELECTTRACE\sand\seither\sSQLITE_DEBUG\sor\sSQLITE_TEST. +D 2014-09-20T18:18:33.584 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -216,7 +216,7 @@ F src/os_win.c 0a4042ef35f322e86fa01f6c8884c5e645b911e7 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/pager.c caab007743821d96752597c9cfd7351654697b06 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 +F src/parse.y 1976d28f168c63c6c14008e9a896620e0c76c25e F src/pcache.c 4121a0571c18581ee9f82f086d5e2030051ebd6a F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa @@ -226,12 +226,12 @@ F src/printf.c 3a47f526b173813d9a7f4e7044007771ba68cde1 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 0cd6706fd52ae5db229e9041094db6ec27195335 -F src/shell.c c00220cdd7f2027780bc25b78376c16dc24e4b7d +F src/select.c 4e00e042994ae38e60576921f78e45311eead49e +F src/shell.c dad23987c34faddb061a339da3e92e05ccc6935e F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 6fd801cac974d310949ddefd6a6c6982c9778f3f +F src/sqliteInt.h 59b0796cd2fa201510ae9850b3b407fa9f997512 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb @@ -1198,8 +1198,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 544664cadfb4e504bc0b321c865d1ecb8a831e20 0fac2c045f47c7735af4eb68ced81d8b43622a1f -R 8acbfeff4e0806bab5948d89d293bcf4 -T +closed 0fac2c045f47c7735af4eb68ced81d8b43622a1f +P 59e2c9df02d7e988c5ad44c560ead1e5288b12e7 +R e5319fc7a5c9cf5efe2dc73e6ab8c7e0 U drh -Z 03e6ed8cf11426837aa81912fc8917d5 +Z 7cccf9f838c01602cd52161c3ac81285 diff --git a/manifest.uuid b/manifest.uuid index 299d8934f2..d3fdcfe339 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -59e2c9df02d7e988c5ad44c560ead1e5288b12e7 \ No newline at end of file +cbe0cf9ddf46f0a678c85d49bfa74e3b7712e1a1 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index dbc129ce63..45e6fae6ad 100644 --- a/src/parse.y +++ b/src/parse.y @@ -459,9 +459,33 @@ multiselect_op(A) ::= UNION(OP). {A = @OP;} multiselect_op(A) ::= UNION ALL. {A = TK_ALL;} multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;} %endif SQLITE_OMIT_COMPOUND_SELECT -oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) +oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); +#if SELECTTRACE_ENABLED + /* Populate the Select.zSelLabel[] string that is used to help with + ** query planner debugging, to differentiate between multiple Select + ** objects in a complex query. + ** + ** If the SELECT keyword is immediately followed by a C-style comment + ** then extract the first few alphanumeric characters from within that + ** comment to be the zSelLabel value. Otherwise, the label is #N where + ** is an integer that is incremented with each SELECT statement seen. + */ + if( A!=0 ){ + const char *z = S.z+6; + int i; + sqlite3_snprintf(sizeof(A->zSelLabel), A->zSelLabel, "#%d", + ++pParse->nSelect); + while( z[0]==' ' ) z++; + if( z[0]=='/' && z[1]=='*' ){ + z += 2; + while( z[0]==' ' ) z++; + for(i=0; sqlite3Isalnum(z[i]); i++){} + sqlite3_snprintf(sizeof(A->zSelLabel), A->zSelLabel, "%.*s", i, z); + } + } +#endif /* SELECTRACE_ENABLED */ } oneselect(A) ::= values(X). {A = X;} diff --git a/src/select.c b/src/select.c index d3ffaf451a..a0f6f35a7f 100644 --- a/src/select.c +++ b/src/select.c @@ -14,6 +14,17 @@ */ #include "sqliteInt.h" +/* +** Trace output macros +*/ +#if SELECTTRACE_ENABLED +/***/ int sqlite3SelectTrace = 0; +# define SELECTTRACE(K,X) if(sqlite3SelectTrace&(K)) sqlite3DebugPrintf X +#else +# define SELECTTRACE(K,X) +#endif + + /* ** An instance of the following object is used to record information about ** how to process the DISTINCT keyword, to simplify passing that information @@ -3355,6 +3366,8 @@ static int flattenSubquery( } /***** If we reach this point, flattening is permitted. *****/ + SELECTTRACE(1, ("flatten %s (term %d) into %s\n", + pSub->zSelLabel, iFrom, p->zSelLabel)); /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; diff --git a/src/shell.c b/src/shell.c index ec83b13910..9745e0ff25 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3101,6 +3101,15 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else + +#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) + if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ + extern int sqlite3SelectTrace; + sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; + }else +#endif + + #ifdef SQLITE_DEBUG /* Undocumented commands for internal testing. Subject to change ** without notice. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 75cfeefa0d..2d63228edd 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -706,6 +706,17 @@ extern const int sqlite3one; # undef SQLITE_ENABLE_STAT3_OR_STAT4 #endif +/* +** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not +** the Select query generator tracing logic is turned on. +*/ +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE)) +# define SELECTTRACE_ENABLED 1 +#else +# define SELECTTRACE_ENABLED 0 +#endif + /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. @@ -2300,6 +2311,9 @@ struct Select { u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */ u16 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ +#if SELECTTRACE_ENABLED + char zSelLabel[12]; /* Text in comment following SELECT keyword */ +#endif int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ u64 nSelectRow; /* Estimated number of result rows */ SrcList *pSrc; /* The FROM clause */ @@ -2558,6 +2572,9 @@ struct Parse { int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ +#if SELECTTRACE_ENABLED + int nSelect; /* Number of SELECT statements seen */ +#endif #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ From 9300adbc79fc7951cd58b9cda9246453381d4344 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 20 Sep 2014 20:24:49 +0000 Subject: [PATCH 61/65] Fix the SELECTTRACE_ENABLE macro so that it doesn't cause problems for testfixture. Add new SELECTTRACE() calls. FossilOrigin-Name: f1ba68f131d2f03e4a7bc50cde23a7609d384279 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 3 +++ src/select.c | 2 ++ src/sqliteInt.h | 3 +-- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index fd7616c7ee..70f1c0adaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sSELECT\squery\splanning\stracing\swhen\scompiled\swith\s\nSQLITE_ENABLE_SELECTTRACE\sand\seither\sSQLITE_DEBUG\sor\sSQLITE_TEST. -D 2014-09-20T18:18:33.584 +C Fix\sthe\sSELECTTRACE_ENABLE\smacro\sso\sthat\sit\sdoesn't\scause\sproblems\sfor\ntestfixture.\s\sAdd\snew\sSELECTTRACE()\scalls. +D 2014-09-20T20:24:49.725 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 19392d98e089640c3336e65b4254cc337efef7d1 +F src/expr.c 51dfaa60c0ec9db231535c98ae9ad5ab1409fd88 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 F src/func.c 1629ccdd8ef3f19d7accc9d9287190489469ff81 @@ -226,12 +226,12 @@ F src/printf.c 3a47f526b173813d9a7f4e7044007771ba68cde1 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 4e00e042994ae38e60576921f78e45311eead49e +F src/select.c a2aac0a26b122b057f02464d6bfeeae3063583e7 F src/shell.c dad23987c34faddb061a339da3e92e05ccc6935e F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 59b0796cd2fa201510ae9850b3b407fa9f997512 +F src/sqliteInt.h 1020906859d2c369d214fd43f52c94385bbd38cc F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb @@ -1198,7 +1198,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 59e2c9df02d7e988c5ad44c560ead1e5288b12e7 -R e5319fc7a5c9cf5efe2dc73e6ab8c7e0 +P cbe0cf9ddf46f0a678c85d49bfa74e3b7712e1a1 +R 0e38789ee4b65d4c643d61f203d35efb U drh -Z 7cccf9f838c01602cd52161c3ac81285 +Z 34fd21290591a3034ab211fbb42794da diff --git a/manifest.uuid b/manifest.uuid index d3fdcfe339..5a4cc52a81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbe0cf9ddf46f0a678c85d49bfa74e3b7712e1a1 \ No newline at end of file +f1ba68f131d2f03e4a7bc50cde23a7609d384279 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c6d8b9e5f3..a1759374c9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1069,6 +1069,9 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); +#if SELECTTRACE_ENABLED + memcpy(pNew->zSelLabel, p->zSelLabel, sizeof(p->zSelLabel)); +#endif return pNew; } #else diff --git a/src/select.c b/src/select.c index a0f6f35a7f..7b2dc4ab9a 100644 --- a/src/select.c +++ b/src/select.c @@ -4612,6 +4612,7 @@ int sqlite3Select( } if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; memset(&sAggInfo, 0, sizeof(sAggInfo)); + SELECTTRACE(1, ("begin processing %s\n", p->zSelLabel)); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); @@ -5367,6 +5368,7 @@ select_end: sqlite3DbFree(db, sAggInfo.aCol); sqlite3DbFree(db, sAggInfo.aFunc); + SELECTTRACE(1, ("end processing %s\n", p->zSelLabel)); return rc; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2d63228edd..ac7f541246 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -710,8 +710,7 @@ extern const int sqlite3one; ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not ** the Select query generator tracing logic is turned on. */ -#if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE)) +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE) # define SELECTTRACE_ENABLED 1 #else # define SELECTTRACE_ENABLED 0 From 7c0a4720ca88e6f9b9c1a423bd74851ab0fbf8fe Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 20 Sep 2014 20:38:48 +0000 Subject: [PATCH 62/65] Candidate fix for [d11a6e908f]. FossilOrigin-Name: 89398880bcfff96e91d2a9c45774f5fb3209ffc1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 17 ++++++++++++++++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 70f1c0adaf..bf6dc5e87d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sSELECTTRACE_ENABLE\smacro\sso\sthat\sit\sdoesn't\scause\sproblems\sfor\ntestfixture.\s\sAdd\snew\sSELECTTRACE()\scalls. -D 2014-09-20T20:24:49.725 +C Candidate\sfix\sfor\s[d11a6e908f]. +D 2014-09-20T20:38:48.213 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -226,7 +226,7 @@ F src/printf.c 3a47f526b173813d9a7f4e7044007771ba68cde1 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c a2aac0a26b122b057f02464d6bfeeae3063583e7 +F src/select.c 3108c73dff614eb8771cd251bed41e3fa5dfe33f F src/shell.c dad23987c34faddb061a339da3e92e05ccc6935e F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad @@ -1198,7 +1198,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 cbe0cf9ddf46f0a678c85d49bfa74e3b7712e1a1 -R 0e38789ee4b65d4c643d61f203d35efb -U drh -Z 34fd21290591a3034ab211fbb42794da +P f1ba68f131d2f03e4a7bc50cde23a7609d384279 +R 9363b1bc0cd8b39c47583b734f41ef37 +U dan +Z 365a1de296dc4c896c5c2cb92f759a75 diff --git a/manifest.uuid b/manifest.uuid index 5a4cc52a81..3be54e6571 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f1ba68f131d2f03e4a7bc50cde23a7609d384279 \ No newline at end of file +89398880bcfff96e91d2a9c45774f5fb3209ffc1 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7b2dc4ab9a..92d4c01b75 100644 --- a/src/select.c +++ b/src/select.c @@ -3561,8 +3561,23 @@ static int flattenSubquery( pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList); } if( pSub->pOrderBy ){ + /* At this point, any non-zero iOrderByCol values indicate that the + ** ORDER BY column expression is identical to the iOrderByCol'th + ** expression returned by SELECT statement pSub. Since these values + ** do not necessarily correspond to columns in SELECT statement pParent, + ** zero them before transfering the ORDER BY clause. + ** + ** Not doing this may cause an error if a subsequent call to this + ** function attempts to flatten a compound sub-query into pParent + ** (the only way this can happen is if the compound sub-query is + ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */ + ExprList *pOrderBy = pSub->pOrderBy; + for(i=0; inExpr; i++){ + pOrderBy->a[i].u.x.iOrderByCol = 0; + } assert( pParent->pOrderBy==0 ); - pParent->pOrderBy = pSub->pOrderBy; + assert( pSub->pPrior==0 ); + pParent->pOrderBy = pOrderBy; pSub->pOrderBy = 0; }else if( pParent->pOrderBy ){ substExprList(db, pParent->pOrderBy, iParent, pSub->pEList); From eb9b884c2db6b81a22b03613d65db7ce2434bda2 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 21 Sep 2014 00:27:26 +0000 Subject: [PATCH 63/65] Improved ".selecttrace" output. FossilOrigin-Name: c0b61f7092a7fd2c5f51db26ce7a7a5c75c227fe --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 4 +--- src/parse.y | 8 ++++---- src/select.c | 42 ++++++++++++++++++++++++++++++++++++------ src/sqliteInt.h | 8 +++++++- 6 files changed, 59 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index bf6dc5e87d..52365602a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Candidate\sfix\sfor\s[d11a6e908f]. -D 2014-09-20T20:38:48.213 +C Improved\s".selecttrace"\soutput. +D 2014-09-21T00:27:26.734 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 51dfaa60c0ec9db231535c98ae9ad5ab1409fd88 +F src/expr.c 4f101c8ddc6d5a22303c88278069f5261562a9a8 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 F src/func.c 1629ccdd8ef3f19d7accc9d9287190489469ff81 @@ -216,7 +216,7 @@ F src/os_win.c 0a4042ef35f322e86fa01f6c8884c5e645b911e7 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 F src/pager.c caab007743821d96752597c9cfd7351654697b06 F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428 -F src/parse.y 1976d28f168c63c6c14008e9a896620e0c76c25e +F src/parse.y b98772da2bb5415970085b707203f92569400aa8 F src/pcache.c 4121a0571c18581ee9f82f086d5e2030051ebd6a F src/pcache.h 9b559127b83f84ff76d735c8262f04853be0c59a F src/pcache1.c dab8ab930d4a73b99768d881185994f34b80ecaa @@ -226,12 +226,12 @@ F src/printf.c 3a47f526b173813d9a7f4e7044007771ba68cde1 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece F src/resolve.c a3466128b52a86c466e47ac1a19e2174f7b5cf89 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 3108c73dff614eb8771cd251bed41e3fa5dfe33f +F src/select.c a83ed8bc2a31c131e3addb6f0488b68334085e7b F src/shell.c dad23987c34faddb061a339da3e92e05ccc6935e F src/sqlite.h.in 8b018219ce988913e5977d5de9ab4beb33be23b6 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 1020906859d2c369d214fd43f52c94385bbd38cc +F src/sqliteInt.h 5ecde2191721a94cdce0d5248e26a373e0b17a70 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2e99ef7ef16187e17033d9398dc962ce22dab5cb @@ -1198,7 +1198,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 f1ba68f131d2f03e4a7bc50cde23a7609d384279 -R 9363b1bc0cd8b39c47583b734f41ef37 -U dan -Z 365a1de296dc4c896c5c2cb92f759a75 +P 89398880bcfff96e91d2a9c45774f5fb3209ffc1 +R 279ae11a33db61e53f043e359f81738d +U drh +Z f68417c1797c667ad48e7e326a25e63f diff --git a/manifest.uuid b/manifest.uuid index 3be54e6571..e355bae159 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -89398880bcfff96e91d2a9c45774f5fb3209ffc1 \ No newline at end of file +c0b61f7092a7fd2c5f51db26ce7a7a5c75c227fe \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a1759374c9..c8e8e78268 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1069,9 +1069,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); -#if SELECTTRACE_ENABLED - memcpy(pNew->zSelLabel, p->zSelLabel, sizeof(p->zSelLabel)); -#endif + sqlite3SelectSetName(pNew, p->zSelName); return pNew; } #else diff --git a/src/parse.y b/src/parse.y index 45e6fae6ad..30a6dc5ff4 100644 --- a/src/parse.y +++ b/src/parse.y @@ -463,26 +463,26 @@ oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y) groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). { A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset); #if SELECTTRACE_ENABLED - /* Populate the Select.zSelLabel[] string that is used to help with + /* Populate the Select.zSelName[] string that is used to help with ** query planner debugging, to differentiate between multiple Select ** objects in a complex query. ** ** If the SELECT keyword is immediately followed by a C-style comment ** then extract the first few alphanumeric characters from within that - ** comment to be the zSelLabel value. Otherwise, the label is #N where + ** comment to be the zSelName value. Otherwise, the label is #N where ** is an integer that is incremented with each SELECT statement seen. */ if( A!=0 ){ const char *z = S.z+6; int i; - sqlite3_snprintf(sizeof(A->zSelLabel), A->zSelLabel, "#%d", + sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "#%d", ++pParse->nSelect); while( z[0]==' ' ) z++; if( z[0]=='/' && z[1]=='*' ){ z += 2; while( z[0]==' ' ) z++; for(i=0; sqlite3Isalnum(z[i]); i++){} - sqlite3_snprintf(sizeof(A->zSelLabel), A->zSelLabel, "%.*s", i, z); + sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "%.*s", i, z); } } #endif /* SELECTRACE_ENABLED */ diff --git a/src/select.c b/src/select.c index 92d4c01b75..7820833643 100644 --- a/src/select.c +++ b/src/select.c @@ -19,9 +19,12 @@ */ #if SELECTTRACE_ENABLED /***/ int sqlite3SelectTrace = 0; -# define SELECTTRACE(K,X) if(sqlite3SelectTrace&(K)) sqlite3DebugPrintf X +# define SELECTTRACE(K,P,S,X) \ + if(sqlite3SelectTrace&(K)) \ + sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",(S)->zSelName,(S)),\ + sqlite3DebugPrintf X #else -# define SELECTTRACE(K,X) +# define SELECTTRACE(K,P,S,X) #endif @@ -137,6 +140,18 @@ Select *sqlite3SelectNew( return pNew; } +#if SELECTTRACE_ENABLED +/* +** Set the name of a Select object +*/ +void sqlite3SelectSetName(Select *p, const char *zName){ + if( p && zName ){ + sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName); + } +} +#endif + + /* ** Delete the given Select structure and all of its substructures. */ @@ -3366,8 +3381,8 @@ static int flattenSubquery( } /***** If we reach this point, flattening is permitted. *****/ - SELECTTRACE(1, ("flatten %s (term %d) into %s\n", - pSub->zSelLabel, iFrom, p->zSelLabel)); + SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n", + pSub->zSelName, pSub, iFrom)); /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; @@ -3420,6 +3435,7 @@ static int flattenSubquery( p->pLimit = 0; p->pOffset = 0; pNew = sqlite3SelectDup(db, p, 0); + sqlite3SelectSetName(pNew, pSub->zSelName); p->pOffset = pOffset; p->pLimit = pLimit; p->pOrderBy = pOrderBy; @@ -3432,6 +3448,9 @@ static int flattenSubquery( if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; p->pPrior = pNew; + SELECTTRACE(2,pParse,p, + ("compound-subquery flattener creates %s.%p as peer\n", + pNew->zSelName, pNew)); } if( db->mallocFailed ) return 1; } @@ -4093,6 +4112,7 @@ static int selectExpander(Walker *pWalker, Select *p){ if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); + sqlite3SelectSetName(pFrom->pSelect, pTab->zName); sqlite3WalkSelect(pWalker, pFrom->pSelect); } #endif @@ -4627,7 +4647,10 @@ int sqlite3Select( } if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; memset(&sAggInfo, 0, sizeof(sAggInfo)); - SELECTTRACE(1, ("begin processing %s\n", p->zSelLabel)); +#if SELECTTRACE_ENABLED + pParse->nSelectIndent++; + SELECTTRACE(1,pParse,p, ("begin processing\n")); +#endif assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); @@ -4784,6 +4807,10 @@ int sqlite3Select( if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); explainSetInteger(pParse->iSelectId, iRestoreSelectId); +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p,("end compound-select processing\n")); + pParse->nSelectIndent--; +#endif return rc; } #endif @@ -5383,7 +5410,10 @@ select_end: sqlite3DbFree(db, sAggInfo.aCol); sqlite3DbFree(db, sAggInfo.aFunc); - SELECTTRACE(1, ("end processing %s\n", p->zSelLabel)); +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p,("end processing\n")); + pParse->nSelectIndent--; +#endif return rc; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ac7f541246..9a9675b0ab 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2311,7 +2311,7 @@ struct Select { u16 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ #if SELECTTRACE_ENABLED - char zSelLabel[12]; /* Text in comment following SELECT keyword */ + char zSelName[12]; /* Symbolic name of this SELECT use for debugging */ #endif int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ u64 nSelectRow; /* Estimated number of result rows */ @@ -2573,6 +2573,7 @@ struct Parse { int nMaxArg; /* Max args passed to user function by sub-program */ #if SELECTTRACE_ENABLED int nSelect; /* Number of SELECT statements seen */ + int nSelectIndent; /* How far to indent SELECTTRACE() output */ #endif #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ @@ -3308,6 +3309,11 @@ ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); IdList *sqlite3IdListDup(sqlite3*,IdList*); Select *sqlite3SelectDup(sqlite3*,Select*,int); +#if SELECTTRACE_ENABLED +void sqlite3SelectSetName(Select*,const char*); +#else +# define sqlite3SelectSetName(A,B) +#endif void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*); FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8); void sqlite3RegisterBuiltinFunctions(sqlite3*); From 249489331cddbdd50e3b6c8dd6ae396b14fe94a0 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 21 Sep 2014 17:51:37 +0000 Subject: [PATCH 64/65] Add the "showauth" extension in ext/misc. FossilOrigin-Name: 28d52c1c38d849f099bc777f5987d1ef89680c2a --- ext/misc/showauth.c | 103 ++++++++++++++++++++++++++++++++++++++++++++ manifest | 11 ++--- manifest.uuid | 2 +- 3 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 ext/misc/showauth.c diff --git a/ext/misc/showauth.c b/ext/misc/showauth.c new file mode 100644 index 0000000000..87a9a6843c --- /dev/null +++ b/ext/misc/showauth.c @@ -0,0 +1,103 @@ +/* +** 2014-09-21 +** +** 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 SQLite extension adds a debug "authorizer" callback to the database +** connection. The callback merely writes the authorization request to +** standard output and returns SQLITE_OK. +** +** This extension can be used (for example) in the command-line shell to +** trace the operation of the authorizer. +*/ +#include "sqlite3ext.h" +SQLITE_EXTENSION_INIT1 +#include + +/* +** Display the authorization request +*/ +static int authCallback( + void *pClientData, + int op, + const char *z1, + const char *z2, + const char *z3, + const char *z4 +){ + const char *zOp; + char zOpSpace[50]; + switch( op ){ + case SQLITE_CREATE_INDEX: zOp = "CREATE_INDEX"; break; + case SQLITE_CREATE_TABLE: zOp = "CREATE_TABLE"; break; + case SQLITE_CREATE_TEMP_INDEX: zOp = "CREATE_TEMP_INDEX"; break; + case SQLITE_CREATE_TEMP_TABLE: zOp = "CREATE_TEMP_TABLE"; break; + case SQLITE_CREATE_TEMP_TRIGGER: zOp = "CREATE_TEMP_TRIGGER"; break; + case SQLITE_CREATE_TEMP_VIEW: zOp = "CREATE_TEMP_VIEW"; break; + case SQLITE_CREATE_TRIGGER: zOp = "CREATE_TRIGGER"; break; + case SQLITE_CREATE_VIEW: zOp = "CREATE_VIEW"; break; + case SQLITE_DELETE: zOp = "DELETE"; break; + case SQLITE_DROP_INDEX: zOp = "DROP_INDEX"; break; + case SQLITE_DROP_TABLE: zOp = "DROP_TABLE"; break; + case SQLITE_DROP_TEMP_INDEX: zOp = "DROP_TEMP_INDEX"; break; + case SQLITE_DROP_TEMP_TABLE: zOp = "DROP_TEMP_TABLE"; break; + case SQLITE_DROP_TEMP_TRIGGER: zOp = "DROP_TEMP_TRIGGER"; break; + case SQLITE_DROP_TEMP_VIEW: zOp = "DROP_TEMP_VIEW"; break; + case SQLITE_DROP_TRIGGER: zOp = "DROP_TRIGGER"; break; + case SQLITE_DROP_VIEW: zOp = "DROP_VIEW"; break; + case SQLITE_INSERT: zOp = "INSERT"; break; + case SQLITE_PRAGMA: zOp = "PRAGMA"; break; + case SQLITE_READ: zOp = "READ"; break; + case SQLITE_SELECT: zOp = "SELECT"; break; + case SQLITE_TRANSACTION: zOp = "TRANSACTION"; break; + case SQLITE_UPDATE: zOp = "UPDATE"; break; + case SQLITE_ATTACH: zOp = "ATTACH"; break; + case SQLITE_DETACH: zOp = "DETACH"; break; + case SQLITE_ALTER_TABLE: zOp = "ALTER_TABLE"; break; + case SQLITE_REINDEX: zOp = "REINDEX"; break; + case SQLITE_ANALYZE: zOp = "ANALYZE"; break; + case SQLITE_CREATE_VTABLE: zOp = "CREATE_VTABLE"; break; + case SQLITE_DROP_VTABLE: zOp = "DROP_VTABLE"; break; + case SQLITE_FUNCTION: zOp = "FUNCTION"; break; + case SQLITE_SAVEPOINT: zOp = "SAVEPOINT"; break; + case SQLITE_COPY: zOp = "COPY"; break; + case SQLITE_RECURSIVE: zOp = "RECURSIVE"; break; + + + default: { + sqlite3_snprintf(sizeof(zOpSpace), zOpSpace, "%d", op); + zOp = zOpSpace; + break; + } + } + if( z1==0 ) z1 = "NULL"; + if( z2==0 ) z2 = "NULL"; + if( z3==0 ) z3 = "NULL"; + if( z4==0 ) z4 = "NULL"; + printf("AUTH: %s,%s,%s,%s,%s\n", zOp, z1, z2, z3, z4); + return SQLITE_OK; +} + + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_showauth_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_set_authorizer(db, authCallback, 0); + return rc; +} diff --git a/manifest b/manifest index 52365602a0..87ce18bc33 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\s".selecttrace"\soutput. -D 2014-09-21T00:27:26.734 +C Add\sthe\s"showauth"\sextension\sin\sext/misc. +D 2014-09-21T17:51:37.899 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -116,6 +116,7 @@ F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a +F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 56739fab8c2ed6a9e2dac5592a88d281a999c43b F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 @@ -1198,7 +1199,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 89398880bcfff96e91d2a9c45774f5fb3209ffc1 -R 279ae11a33db61e53f043e359f81738d +P c0b61f7092a7fd2c5f51db26ce7a7a5c75c227fe +R 90118272bfe5d13644b89a2578b8154b U drh -Z f68417c1797c667ad48e7e326a25e63f +Z 3c4b3bea487974dee315367e89ebebc8 diff --git a/manifest.uuid b/manifest.uuid index e355bae159..4be4543ac6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0b61f7092a7fd2c5f51db26ce7a7a5c75c227fe \ No newline at end of file +28d52c1c38d849f099bc777f5987d1ef89680c2a \ No newline at end of file From d7643037e6336191c5fe5bb009e1ab2b88677701 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 21 Sep 2014 20:31:26 +0000 Subject: [PATCH 65/65] Add test cases for ticket [89398880bcfff9]. FossilOrigin-Name: 9683e001ed38b41979220eef0bdfcb54df5f3191 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/subquery2.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 87ce18bc33..b1705d3f7d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"showauth"\sextension\sin\sext/misc. -D 2014-09-21T17:51:37.899 +C Add\stest\scases\sfor\sticket\s[89398880bcfff9]. +D 2014-09-21T20:31:26.194 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -862,7 +862,7 @@ F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9 -F test/subquery2.test 91e1e364072aeff431d1f9689b15147e421d88c7 +F test/subquery2.test 438f8a7da1457277b22e4176510f7659b286995f F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 @@ -1199,7 +1199,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 c0b61f7092a7fd2c5f51db26ce7a7a5c75c227fe -R 90118272bfe5d13644b89a2578b8154b +P 28d52c1c38d849f099bc777f5987d1ef89680c2a +R df45958fe8f93552efb788581c98f0f7 U drh -Z 3c4b3bea487974dee315367e89ebebc8 +Z e77b30925e1036bea887cc5097672af2 diff --git a/manifest.uuid b/manifest.uuid index 4be4543ac6..f4ca445f31 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28d52c1c38d849f099bc777f5987d1ef89680c2a \ No newline at end of file +9683e001ed38b41979220eef0bdfcb54df5f3191 \ No newline at end of file diff --git a/test/subquery2.test b/test/subquery2.test index 4406efccf2..de637d5d25 100644 --- a/test/subquery2.test +++ b/test/subquery2.test @@ -103,5 +103,50 @@ do_execsql_test 2.2 { LIMIT (SELECT a FROM t5) } {2 3 3 6 4 10} +############################################################################ +# Ticket http://www.sqlite.org/src/info/d11a6e908f (2014-09-20) +# Query planner fault on three-way nested join with compound inner SELECT +# +do_execsql_test 3.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1 (id INTEGER PRIMARY KEY, data TEXT); + INSERT INTO t1(id,data) VALUES(9,'nine-a'); + INSERT INTO t1(id,data) VALUES(10,'ten-a'); + INSERT INTO t1(id,data) VALUES(11,'eleven-a'); + CREATE TABLE t2 (id INTEGER PRIMARY KEY, data TEXT); + INSERT INTO t2(id,data) VALUES(9,'nine-b'); + INSERT INTO t2(id,data) VALUES(10,'ten-b'); + INSERT INTO t2(id,data) VALUES(11,'eleven-b'); + + SELECT id FROM ( + SELECT id,data FROM ( + SELECT * FROM t1 UNION ALL SELECT * FROM t2 + ) + WHERE id=10 ORDER BY data + ); +} {10 10} +do_execsql_test 3.1 { + SELECT data FROM ( + SELECT 'dummy', data FROM ( + SELECT data FROM t1 UNION ALL SELECT data FROM t1 + ) ORDER BY data + ); +} {eleven-a eleven-a nine-a nine-a ten-a ten-a} +do_execsql_test 3.2 { + DROP TABLE IF EXISTS t3; + DROP TABLE IF EXISTS t4; + CREATE TABLE t3(id INTEGER, data TEXT); + CREATE TABLE t4(id INTEGER, data TEXT); + INSERT INTO t3 VALUES(4, 'a'),(2,'c'); + INSERT INTO t4 VALUES(3, 'b'),(1,'d'); + + SELECT data, id FROM ( + SELECT id, data FROM ( + SELECT * FROM t3 UNION ALL SELECT * FROM t4 + ) ORDER BY data + ); +} {a 4 b 3 c 2 d 1} + finish_test