Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Pull the latest trunk changes into the apple-osx branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | apple-osx |
Files: | files | file ages | folders |
SHA1: |
4fa9ee794713e7a2298f53d9b517c907 |
User & Date: | drh 2011-10-31 14:42:31.165 |
Context
2011-10-31
| ||
19:34 | Fix the os_unix.c source file so that it will build as part of an amalgamation on non-apple platforms. (check-in: b2f7639c8f user: drh tags: apple-osx) | |
14:42 | Pull the latest trunk changes into the apple-osx branch. (check-in: 4fa9ee7947 user: drh tags: apple-osx) | |
12:25 | Fix a typo in a comment. No code changes. (check-in: 6635cd9a77 user: drh tags: trunk) | |
2011-10-21
| ||
17:18 | Merge the latest trunk changes into the apple-osx branch. (check-in: be62ef058b user: drh tags: apple-osx) | |
Changes
Added ext/fts3/README.content.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | FTS4 CONTENT OPTION Normally, in order to create a full-text index on a dataset, the FTS4 module stores a copy of all indexed documents in a specially created database table. As of SQLite version 3.7.9, FTS4 supports a new option - "content" - designed to extend FTS4 to support the creation of full-text indexes where: * The indexed documents are not stored within the SQLite database at all (a "contentless" FTS4 table), or * The indexed documents are stored in a database table created and managed by the user (an "external content" FTS4 table). Because the indexed documents themselves are usually much larger than the full-text index, the content option can sometimes be used to achieve significant space savings. CONTENTLESS FTS4 TABLES In order to create an FTS4 table that does not store a copy of the indexed documents at all, the content option should be set to an empty string. For example, the following SQL creates such an FTS4 table with three columns - "a", "b", and "c": CREATE VIRTUAL TABLE t1 USING fts4(content="", a, b, c); Data can be inserted into such an FTS4 table using an INSERT statements. However, unlike ordinary FTS4 tables, the user must supply an explicit integer docid value. For example: -- This statement is Ok: INSERT INTO t1(docid, a, b, c) VALUES(1, 'a b c', 'd e f', 'g h i'); -- This statement causes an error, as no docid value has been provided: INSERT INTO t1(a, b, c) VALUES('j k l', 'm n o', 'p q r'); It is not possible to UPDATE or DELETE a row stored in a contentless FTS4 table. Attempting to do so is an error. Contentless FTS4 tables also support SELECT statements. However, it is an error to attempt to retrieve the value of any table column other than the docid column. The auxiliary function matchinfo() may be used, but snippet() and offsets() may not. For example: -- The following statements are Ok: SELECT docid FROM t1 WHERE t1 MATCH 'xxx'; SELECT docid FROM t1 WHERE a MATCH 'xxx'; SELECT matchinfo(t1) FROM t1 WHERE t1 MATCH 'xxx'; -- The following statements all cause errors, as the value of columns -- other than docid are required to evaluate them. SELECT * FROM t1; SELECT a, b FROM t1 WHERE t1 MATCH 'xxx'; SELECT docid FROM t1 WHERE a LIKE 'xxx%'; SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'xxx'; Errors related to attempting to retrieve column values other than docid are runtime errors that occur within sqlite3_step(). In some cases, for example if the MATCH expression in a SELECT query matches zero rows, there may be no error at all even if a statement does refer to column values other than docid. EXTERNAL CONTENT FTS4 TABLES An "external content" FTS4 table is similar to a contentless table, except that if evaluation of a query requires the value of a column other than docid, FTS4 attempts to retrieve that value from a table (or view, or virtual table) nominated by the user (hereafter referred to as the "content table"). The FTS4 module never writes to the content table, and writing to the content table does not affect the full-text index. It is the responsibility of the user to ensure that the content table and the full-text index are consistent. An external content FTS4 table is created by setting the content option to the name of a table (or view, or virtual table) that may be queried by FTS4 to retrieve column values when required. If the nominated table does not exist, then an external content table behaves in the same way as a contentless table. For example: CREATE TABLE t2(id INTEGER PRIMARY KEY, a, b, c); CREATE VIRTUAL TABLE t3 USING fts4(content="t2", a, c); Assuming the nominated table does exist, then its columns must be the same as or a superset of those defined for the FTS table. When a users query on the FTS table requires a column value other than docid, FTS attempts to read this value from the corresponding column of the row in the content table with a rowid value equal to the current FTS docid. Or, if such a row cannot be found in the content table, a NULL value is used instead. For example: CREATE TABLE t2(id INTEGER PRIMARY KEY, a, b, c, d); CREATE VIRTUAL TABLE t3 USING fts4(content="t2", b, c); INSERT INTO t2 VALUES(2, 'a b', 'c d', 'e f'); INSERT INTO t2 VALUES(3, 'g h', 'i j', 'k l'); INSERT INTO t3(docid, b, c) SELECT id, b, c FROM t2; -- The following query returns a single row with two columns containing -- the text values "i j" and "k l". -- -- The query uses the full-text index to discover that the MATCH -- term matches the row with docid=3. It then retrieves the values -- of columns b and c from the row with rowid=3 in the content table -- to return. -- SELECT * FROM t3 WHERE t3 MATCH 'k'; -- Following the UPDATE, the query still returns a single row, this -- time containing the text values "xxx" and "yyy". This is because the -- full-text index still indicates that the row with docid=3 matches -- the FTS4 query 'k', even though the documents stored in the content -- table have been modified. -- UPDATE t2 SET b = 'xxx', c = 'yyy' WHERE rowid = 3; SELECT * FROM t3 WHERE t3 MATCH 'k'; -- Following the DELETE below, the query returns one row containing two -- NULL values. NULL values are returned because FTS is unable to find -- a row with rowid=3 within the content table. -- DELETE FROM t2; SELECT * FROM t3 WHERE t3 MATCH 'k'; When a row is deleted from an external content FTS4 table, FTS4 needs to retrieve the column values of the row being deleted from the content table. This is so that FTS4 can update the full-text index entries for each token that occurs within the deleted row to indicate that that row has been deleted. If the content table row cannot be found, or if it contains values inconsistent with the contents of the FTS index, the results can be difficult to predict. The FTS index may be left containing entries corresponding to the deleted row, which can lead to seemingly nonsensical results being returned by subsequent SELECT queries. The same applies when a row is updated, as internally an UPDATE is the same as a DELETE followed by an INSERT. Instead of writing separately to the full-text index and the content table, some users may wish to use database triggers to keep the full-text index up to date with respect to the set of documents stored in the content table. For example, using the tables from earlier examples: CREATE TRIGGER t2_bu BEFORE UPDATE ON t2 BEGIN DELETE FROM t3 WHERE docid=old.rowid; END; CREATE TRIGGER t2_bd BEFORE DELETE ON t2 BEGIN DELETE FROM t3 WHERE docid=old.rowid; END; CREATE TRIGGER t2_bu AFTER UPDATE ON t2 BEGIN INSERT INTO t3(docid, b, c) VALUES(new.rowid, new.b, new.c); END; CREATE TRIGGER t2_bd AFTER INSERT ON t2 BEGIN INSERT INTO t3(docid, b, c) VALUES(new.rowid, new.b, new.c); END; The DELETE trigger must be fired before the actual delete takes place on the content table. This is so that FTS4 can still retrieve the original values in order to update the full-text index. And the INSERT trigger must be fired after the new row is inserted, so as to handle the case where the rowid is assigned automatically within the system. The UPDATE trigger must be split into two parts, one fired before and one after the update of the content table, for the same reasons. FTS4 features a special command similar to the 'optimize' command that deletes the entire full-text index and rebuilds it based on the current set of documents in the content table. Assuming again that "t3" is the name of the external content FTS4 table, the command is: INSERT INTO t3(t3) VALUES('rebuild'); This command may also be used with ordinary FTS4 tables, although it may only be useful if the full-text index has somehow become corrupt. It is an error to attempt to rebuild the full-text index maintained by a contentless FTS4 table. |
Changes to src/analyze.c.
︙ | ︙ | |||
115 116 117 118 119 120 121 | */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table for ** writing with cursor iStatCur. If the library was built with the | | | | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" /* ** This routine generates code that opens the sqlite_stat1 table for ** writing with cursor iStatCur. If the library was built with the ** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is ** opened for writing using cursor (iStatCur+1) ** ** If the sqlite_stat1 tables does not previously exist, it is created. ** Similarly, if the sqlite_stat3 table does not exist and the library ** is compiled with SQLITE_ENABLE_STAT3 defined, it is created. ** ** Argument zWhere may be a pointer to a buffer containing a table name, ** or it may be a NULL pointer. If it is not NULL, then all entries in ** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated ** with the named table are deleted. If zWhere==0, then code is generated ** to delete all stat table entries. */ static void openStatTable( Parse *pParse, /* Parsing context */ int iDb, /* The database we are looking in */ int iStatCur, /* Open the sqlite_stat1 table on this cursor */ |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
1977 1978 1979 1980 1981 1982 1983 | iDestroyed = iLargest; } } #endif } /* | | < < < < < | > > | | | 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 | iDestroyed = iLargest; } } #endif } /* ** Remove entries from the sqlite_statN tables (for N in (1,2,3)) ** after a DROP INDEX or DROP TABLE command. */ static void sqlite3ClearStatTables( Parse *pParse, /* The parsing context */ int iDb, /* The database number */ const char *zType, /* "idx" or "tbl" */ const char *zName /* Name of index or table */ ){ int i; const char *zDbName = pParse->db->aDb[iDb].zName; for(i=1; i<=3; i++){ char zTab[24]; sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", zDbName, zTab, zType, zName ); } } } /* ** Generate code to drop a table. |
︙ | ︙ |
Changes to src/ctime.c.
︙ | ︙ | |||
110 111 112 113 114 115 116 | #endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif #ifdef SQLITE_ENABLE_RTREE "ENABLE_RTREE", #endif | < < < | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | #endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif #ifdef SQLITE_ENABLE_RTREE "ENABLE_RTREE", #endif #ifdef SQLITE_ENABLE_STAT3 "ENABLE_STAT3", #endif #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY "ENABLE_UNLOCK_NOTIFY", #endif #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
738 739 740 741 742 743 744 | ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. ** ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the ** windows [VFS] in order to work to provide robustness against ** anti-virus programs. By default, the windows VFS will retry file read, | | | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 | ** opcode as doing so may disrupt the operation of the specialized VFSes ** that do require it. ** ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** retry counts and intervals for certain disk I/O operations for the ** windows [VFS] in order to work to provide robustness against ** anti-virus programs. By default, the windows VFS will retry file read, ** file write, and file delete operations up to 10 times, with a delay ** of 25 milliseconds before the first retry and with the delay increasing ** by an additional 25 milliseconds with each subsequent retry. This ** opcode allows those to values (10 retries and 25 milliseconds of delay) ** to be adjusted. The values are changed for all database connections ** within the same process. The argument is a pointer to an array of two ** integers where the first integer i the new retry count and the second ** integer is the delay. If either integer is negative, then the setting |
︙ | ︙ |
Changes to src/sqlite3ext.h.
︙ | ︙ | |||
45 46 47 48 49 50 51 | int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); int (*busy_timeout)(sqlite3*,int ms); int (*changes)(sqlite3*); int (*close)(sqlite3*); | | > | > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); int (*busy_timeout)(sqlite3*,int ms); int (*changes)(sqlite3*); int (*close)(sqlite3*); int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, int eTextRep,const char*)); int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, int eTextRep,const void*)); const void * (*column_blob)(sqlite3_stmt*,int iCol); int (*column_bytes)(sqlite3_stmt*,int iCol); int (*column_bytes16)(sqlite3_stmt*,int iCol); int (*column_count)(sqlite3_stmt*pStmt); const char * (*column_database_name)(sqlite3_stmt*,int); const void * (*column_database_name16)(sqlite3_stmt*,int); const char * (*column_decltype)(sqlite3_stmt*,int i); |
︙ | ︙ | |||
71 72 73 74 75 76 77 | const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); const void * (*column_text16)(sqlite3_stmt*,int iCol); int (*column_type)(sqlite3_stmt*,int iCol); sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); void * (*commit_hook)(sqlite3*,int(*)(void*),void*); int (*complete)(const char*sql); int (*complete16)(const void*sql); | | > | > | > > > | > > > | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); const void * (*column_text16)(sqlite3_stmt*,int iCol); int (*column_type)(sqlite3_stmt*,int iCol); sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); void * (*commit_hook)(sqlite3*,int(*)(void*),void*); int (*complete)(const char*sql); int (*complete16)(const void*sql); int (*create_collation)(sqlite3*,const char*,int,void*, int(*)(void*,int,const void*,int,const void*)); int (*create_collation16)(sqlite3*,const void*,int,void*, int(*)(void*,int,const void*,int,const void*)); int (*create_function)(sqlite3*,const char*,int,int,void*, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*)); int (*create_function16)(sqlite3*,const void*,int,int,void*, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*)); int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); int (*data_count)(sqlite3_stmt*pStmt); sqlite3 * (*db_handle)(sqlite3_stmt*); int (*declare_vtab)(sqlite3*,const char*); int (*enable_shared_cache)(int); int (*errcode)(sqlite3*db); const char * (*errmsg)(sqlite3*); |
︙ | ︙ | |||
119 120 121 122 123 124 125 | void (*result_null)(sqlite3_context*); void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_value)(sqlite3_context*,sqlite3_value*); void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); | | > | > | > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | void (*result_null)(sqlite3_context*); void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); void (*result_value)(sqlite3_context*,sqlite3_value*); void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, const char*,const char*),void*); void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); char * (*snprintf)(int,char*,const char*,...); int (*step)(sqlite3_stmt*); int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, char const**,char const**,int*,int*,int*); void (*thread_cleanup)(void); int (*total_changes)(sqlite3*); void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, sqlite_int64),void*); void * (*user_data)(sqlite3_context*); const void * (*value_blob)(sqlite3_value*); int (*value_bytes)(sqlite3_value*); int (*value_bytes16)(sqlite3_value*); double (*value_double)(sqlite3_value*); int (*value_int)(sqlite3_value*); sqlite_int64 (*value_int64)(sqlite3_value*); |
︙ | ︙ | |||
150 151 152 153 154 155 156 | /* Added ??? */ int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); /* Added by 3.3.13 */ int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); int (*clear_bindings)(sqlite3_stmt*); /* Added by 3.4.1 */ | | > | > | > > | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | /* Added ??? */ int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); /* Added by 3.3.13 */ int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); int (*clear_bindings)(sqlite3_stmt*); /* Added by 3.4.1 */ int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, void (*xDestroy)(void *)); /* Added by 3.5.0 */ int (*bind_zeroblob)(sqlite3_stmt*,int,int); int (*blob_bytes)(sqlite3_blob*); int (*blob_close)(sqlite3_blob*); int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, int,sqlite3_blob**); int (*blob_read)(sqlite3_blob*,void*,int,int); int (*blob_write)(sqlite3_blob*,const void*,int,int); int (*create_collation_v2)(sqlite3*,const char*,int,void*, int(*)(void*,int,const void*,int,const void*), void(*)(void*)); int (*file_control)(sqlite3*,const char*,int,void*); sqlite3_int64 (*memory_highwater)(int); sqlite3_int64 (*memory_used)(void); sqlite3_mutex *(*mutex_alloc)(int); void (*mutex_enter)(sqlite3_mutex*); void (*mutex_free)(sqlite3_mutex*); void (*mutex_leave)(sqlite3_mutex*); |
︙ | ︙ | |||
194 195 196 197 198 199 200 | int (*backup_finish)(sqlite3_backup*); sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); int (*backup_pagecount)(sqlite3_backup*); int (*backup_remaining)(sqlite3_backup*); int (*backup_step)(sqlite3_backup*,int); const char *(*compileoption_get)(int); int (*compileoption_used)(const char*); | | > > > > | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | int (*backup_finish)(sqlite3_backup*); sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); int (*backup_pagecount)(sqlite3_backup*); int (*backup_remaining)(sqlite3_backup*); int (*backup_step)(sqlite3_backup*,int); const char *(*compileoption_get)(int); int (*compileoption_used)(const char*); int (*create_function_v2)(sqlite3*,const char*,int,int,void*, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*)); int (*db_config)(sqlite3*,int,...); sqlite3_mutex *(*db_mutex)(sqlite3*); int (*db_status)(sqlite3*,int,int*,int*,int); int (*extended_errcode)(sqlite3*); void (*log)(int,const char*,...); sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); const char *(*sourceid)(void); |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
72 73 74 75 76 77 78 | #ifdef HAVE_STDINT_H #include <stdint.h> #endif #ifdef HAVE_INTTYPES_H #include <inttypes.h> #endif | < < < < < < < | 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | #ifdef HAVE_STDINT_H #include <stdint.h> #endif #ifdef HAVE_INTTYPES_H #include <inttypes.h> #endif /* ** The following macros are used to cast pointers to integers and ** integers to pointers. The way you do this varies from one compiler ** to the next, so we have developed the following set of #if statements ** to generate appropriate macros for a wide range of compilers. ** ** The correct "ANSI" way to do this is to use the intptr_t type. |
︙ | ︙ | |||
1520 1521 1522 1523 1524 1525 1526 | int nSample; /* Number of elements in aSample[] */ tRowcnt avgEq; /* Average nEq value for key values not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ #endif }; /* | | | > | 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 | int nSample; /* Number of elements in aSample[] */ tRowcnt avgEq; /* Average nEq value for key values not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ #endif }; /* ** Each sample stored in the sqlite_stat3 table is represented in memory ** using a structure of this type. See documentation at the top of the ** analyze.c source file for additional information. */ struct IndexSample { union { char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ double r; /* Value if eType is SQLITE_FLOAT */ i64 i; /* Value if eType is SQLITE_INTEGER */ } u; |
︙ | ︙ |
Changes to src/test8.c.
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 | ); rc = sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } /* ** A virtual table module that merely "echos" the contents of another ** table (like an SQL VIEW). */ static sqlite3_module echoModule = { | > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > | 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 | ); rc = sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } static int echoSavepoint(sqlite3_vtab *pVTab, int iSavepoint){ assert( pVTab ); return SQLITE_OK; } static int echoRelease(sqlite3_vtab *pVTab, int iSavepoint){ assert( pVTab ); return SQLITE_OK; } static int echoRollbackTo(sqlite3_vtab *pVTab, int iSavepoint){ assert( pVTab ); return SQLITE_OK; } /* ** A virtual table module that merely "echos" the contents of another ** table (like an SQL VIEW). */ static sqlite3_module echoModule = { 1, /* iVersion */ echoCreate, echoConnect, echoBestIndex, echoDisconnect, echoDestroy, echoOpen, /* xOpen - open a cursor */ echoClose, /* xClose - close a cursor */ echoFilter, /* xFilter - configure scan constraints */ echoNext, /* xNext - advance a cursor */ echoEof, /* xEof */ echoColumn, /* xColumn - read data */ echoRowid, /* xRowid - read data */ echoUpdate, /* xUpdate - write data */ echoBegin, /* xBegin - begin transaction */ echoSync, /* xSync - sync transaction */ echoCommit, /* xCommit - commit transaction */ echoRollback, /* xRollback - rollback transaction */ echoFindFunction, /* xFindFunction - function overloading */ echoRename /* xRename - rename the table */ }; static sqlite3_module echoModuleV2 = { 2, /* iVersion */ echoCreate, echoConnect, echoBestIndex, echoDisconnect, echoDestroy, echoOpen, /* xOpen - open a cursor */ echoClose, /* xClose - close a cursor */ echoFilter, /* xFilter - configure scan constraints */ echoNext, /* xNext - advance a cursor */ echoEof, /* xEof */ echoColumn, /* xColumn - read data */ echoRowid, /* xRowid - read data */ echoUpdate, /* xUpdate - write data */ echoBegin, /* xBegin - begin transaction */ echoSync, /* xSync - sync transaction */ echoCommit, /* xCommit - commit transaction */ echoRollback, /* xRollback - rollback transaction */ echoFindFunction, /* xFindFunction - function overloading */ echoRename, /* xRename - rename the table */ echoSavepoint, echoRelease, echoRollbackTo }; /* ** Decode a pointer to an sqlite3 object. */ extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); |
︙ | ︙ | |||
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | sqlite3 *db; EchoModule *pMod; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; pMod = sqlite3_malloc(sizeof(EchoModule)); pMod->interp = interp; sqlite3_create_module_v2(db, "echo", &echoModule, (void*)pMod, moduleDestroy); return TCL_OK; } /* ** Tcl interface to sqlite3_declare_vtab, invoked as follows from Tcl: ** ** sqlite3_declare_vtab DB SQL | > > > > > > > > > | 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 | sqlite3 *db; EchoModule *pMod; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; /* Virtual table module "echo" */ pMod = sqlite3_malloc(sizeof(EchoModule)); pMod->interp = interp; sqlite3_create_module_v2(db, "echo", &echoModule, (void*)pMod, moduleDestroy); /* Virtual table module "echo_v2" */ pMod = sqlite3_malloc(sizeof(EchoModule)); pMod->interp = interp; sqlite3_create_module_v2(db, "echo_v2", &echoModuleV2, (void*)pMod, moduleDestroy ); return TCL_OK; } /* ** Tcl interface to sqlite3_declare_vtab, invoked as follows from Tcl: ** ** sqlite3_declare_vtab DB SQL |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
420 421 422 423 424 425 426 | #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); #endif | < < < < < < | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_ENABLE_STAT3 Tcl_SetVar2(interp, "sqlite_options", "stat3", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "stat3", "0", TCL_GLOBAL_ONLY); #endif #if !defined(SQLITE_ENABLE_LOCKING_STYLE) |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
4300 4301 4302 4303 4304 4305 4306 | BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; | < | < > | 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 | BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; res = 0; if( ALWAYS(pCrsr!=0) ){ rc = sqlite3BtreeLast(pCrsr, &res); } pC->nullRow = (u8)res; pC->deferredMoveto = 0; pC->rowidIsValid = 0; pC->cacheStatus = CACHE_STALE; if( pOp->p2>0 && res ){ |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
391 392 393 394 395 396 397 398 399 400 401 402 403 404 | int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); void sqlite3VdbeMemStoreType(Mem *pMem); #ifdef SQLITE_OMIT_MERGE_SORT # define sqlite3VdbeSorterInit(Y,Z) SQLITE_OK # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK # define sqlite3VdbeSorterClose(Y,Z) # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK | > | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); int sqlite3VdbeCloseStatement(Vdbe *, int); void sqlite3VdbeFrameDelete(VdbeFrame*); int sqlite3VdbeFrameRestore(VdbeFrame *); void sqlite3VdbeMemStoreType(Mem *pMem); int sqlite3VdbeTransferError(Vdbe *p); #ifdef SQLITE_OMIT_MERGE_SORT # define sqlite3VdbeSorterInit(Y,Z) SQLITE_OK # define sqlite3VdbeSorterWrite(X,Y,Z) SQLITE_OK # define sqlite3VdbeSorterClose(Y,Z) # define sqlite3VdbeSorterRowkey(Y,Z) SQLITE_OK # define sqlite3VdbeSorterRewind(X,Y,Z) SQLITE_OK |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
467 468 469 470 471 472 473 | ); assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE ); if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ /* If this statement was prepared using sqlite3_prepare_v2(), and an ** error has occured, then return the error code in p->rc to the ** caller. Set the error code in the database handle to the same value. */ | | | 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 | ); assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE ); if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ /* If this statement was prepared using sqlite3_prepare_v2(), and an ** error has occured, then return the error code in p->rc to the ** caller. Set the error code in the database handle to the same value. */ rc = sqlite3VdbeTransferError(p); } return (rc&db->errMask); } /* ** The maximum number of times that a statement will try to reparse ** itself before giving up and returning SQLITE_SCHEMA. |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 | /* ** Each VDBE holds the result of the most recent sqlite3_step() call ** in p->rc. This routine sets that result back to SQLITE_OK. */ void sqlite3VdbeResetStepResult(Vdbe *p){ p->rc = SQLITE_OK; } /* ** Clean up a VDBE after execution but do not delete the VDBE just yet. ** Write any error messages into *pzErrMsg. Return the result code. ** ** After this routine is run, the VDBE should be ready to be executed ** again. | > > > > > > > > > > > > > > > > > > > > > > > > | 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 | /* ** Each VDBE holds the result of the most recent sqlite3_step() call ** in p->rc. This routine sets that result back to SQLITE_OK. */ void sqlite3VdbeResetStepResult(Vdbe *p){ p->rc = SQLITE_OK; } /* ** Copy the error code and error message belonging to the VDBE passed ** as the first argument to its database handle (so that they will be ** returned by calls to sqlite3_errcode() and sqlite3_errmsg()). ** ** This function does not clear the VDBE error code or message, just ** copies them to the database handle. */ int sqlite3VdbeTransferError(Vdbe *p){ sqlite3 *db = p->db; int rc = p->rc; if( p->zErrMsg ){ u8 mallocFailed = db->mallocFailed; sqlite3BeginBenignMalloc(); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3EndBenignMalloc(); db->mallocFailed = mallocFailed; db->errCode = rc; }else{ sqlite3Error(db, rc, 0); } return rc; } /* ** Clean up a VDBE after execution but do not delete the VDBE just yet. ** Write any error messages into *pzErrMsg. Return the result code. ** ** After this routine is run, the VDBE should be ready to be executed ** again. |
︙ | ︙ | |||
2335 2336 2337 2338 2339 2340 2341 | /* If the VDBE has be run even partially, then transfer the error code ** and error message from the VDBE into the main database structure. But ** if the VDBE has just been set to run but has not actually executed any ** instructions yet, leave the main database error information unchanged. */ if( p->pc>=0 ){ | < < < | < | | < < < < < | 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 | /* If the VDBE has be run even partially, then transfer the error code ** and error message from the VDBE into the main database structure. But ** if the VDBE has just been set to run but has not actually executed any ** instructions yet, leave the main database error information unchanged. */ if( p->pc>=0 ){ sqlite3VdbeTransferError(p); sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; if( p->runOnlyOnce ) p->expired = 1; }else if( p->rc && p->expired ){ /* The expired flag was set on the VDBE before the first call ** to sqlite3_step(). For consistency (since sqlite3_step() was ** called), set the database error in this case as well. */ sqlite3Error(db, p->rc, 0); |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
887 888 889 890 891 892 893 | assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); assert( iSavepoint>=0 ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ VTable *pVTab = db->aVTrans[i]; const sqlite3_module *pMod = pVTab->pMod->pModule; | | | | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 | assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); assert( iSavepoint>=0 ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ VTable *pVTab = db->aVTrans[i]; const sqlite3_module *pMod = pVTab->pMod->pModule; if( pVTab->pVtab && pMod->iVersion>=2 ){ int (*xMethod)(sqlite3_vtab *, int); switch( op ){ case SAVEPOINT_BEGIN: xMethod = pMod->xSavepoint; pVTab->iSavepoint = iSavepoint+1; break; case SAVEPOINT_ROLLBACK: xMethod = pMod->xRollbackTo; break; default: xMethod = pMod->xRelease; break; } if( xMethod && pVTab->iSavepoint>iSavepoint ){ rc = xMethod(pVTab->pVtab, iSavepoint); } } } } return rc; } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
3163 3164 3165 3166 3167 3168 3169 | ** to do a binary search to locate a row in a table or index is roughly ** log10(N) times the time to move from one row to the next row within ** a table or index. The actual times can vary, with the size of ** records being an important factor. Both moves and searches are ** slower with larger records, presumably because fewer records fit ** on one page and hence more pages have to be fetched. ** | | | 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 | ** to do a binary search to locate a row in a table or index is roughly ** log10(N) times the time to move from one row to the next row within ** a table or index. The actual times can vary, with the size of ** records being an important factor. Both moves and searches are ** slower with larger records, presumably because fewer records fit ** on one page and hence more pages have to be fetched. ** ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do ** not give us data on the relative sizes of table and index records. ** So this computation assumes table records are about twice as big ** as index records */ if( (wsFlags & WHERE_NOT_FULLSCAN)==0 ){ /* The cost of a full table scan is a number of move operations equal ** to the number of rows in the table. |
︙ | ︙ |
Changes to test/alter.test.
︙ | ︙ | |||
842 843 844 845 846 847 848 | #------------------------------------------------------------------------- # Test that it is not possible to use ALTER TABLE on any system table. # set system_table_list {1 sqlite_master} catchsql ANALYZE ifcapable analyze { lappend system_table_list 2 sqlite_stat1 } | < | 842 843 844 845 846 847 848 849 850 851 852 853 854 855 | #------------------------------------------------------------------------- # Test that it is not possible to use ALTER TABLE on any system table. # set system_table_list {1 sqlite_master} catchsql ANALYZE ifcapable analyze { lappend system_table_list 2 sqlite_stat1 } ifcapable stat3 { lappend system_table_list 4 sqlite_stat3 } foreach {tn tbl} $system_table_list { do_test alter-15.$tn.1 { catchsql "ALTER TABLE $tbl RENAME TO xyz" } [list 1 "table $tbl may not be altered"] |
︙ | ︙ |
Deleted test/analyze2.test.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to test/analyze3.test.
︙ | ︙ | |||
66 67 68 69 70 71 72 | # INTEGER) with integer values from 100 to 1100. Create an index on this # column. ANALYZE the table. # # analyze3-1.1.2 - 3.1.3 # Show that there are two possible plans for querying the table with # a range constraint on the indexed column - "full table scan" or "use # the index". When the range is specified using literal values, SQLite | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | # INTEGER) with integer values from 100 to 1100. Create an index on this # column. ANALYZE the table. # # analyze3-1.1.2 - 3.1.3 # Show that there are two possible plans for querying the table with # a range constraint on the indexed column - "full table scan" or "use # the index". When the range is specified using literal values, SQLite # is able to pick the best plan based on the samples in sqlite_stat3. # # analyze3-1.1.4 - 3.1.9 # Show that using SQL variables produces the same results as using # literal values to constrain the range scan. # # These tests also check that the compiler code considers column # affinities when estimating the number of rows scanned by the "use |
︙ | ︙ |
Changes to test/auth.test.
︙ | ︙ | |||
2317 2318 2319 2320 2321 2322 2323 | } ifcapable view { execsql { DROP TABLE v1chng; } } } | < < < | | | | < | | 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 | } ifcapable view { execsql { DROP TABLE v1chng; } } } ifcapable stat3 { set stat3 "sqlite_stat3 " } else { set stat3 "" } do_test auth-5.2 { execsql { SELECT name FROM ( SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type='table' ORDER BY name } } "sqlite_stat1 ${stat3}t1 t2 t3 t4" } # Ticket #3944 # ifcapable trigger { do_test auth-5.3.1 { execsql { |
︙ | ︙ |
Added test/errmsg.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | # 2001 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. # #*********************************************************************** # Test that if sqlite3_prepare_v2() is used to prepare a query, the # error-message associated with an sqlite3_step() error is available # immediately. Whereas if sqlite3_prepare() is used, it is not available # until sqlite3_finalize() or sqlite3_reset() has been called. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix errmsg # Test organization: # # errmsg-1.* User-defined SQL function errors # errmsg-2.* Errors generated by the VDBE (constraint failures etc.) # errmsg-3.* SQLITE_SCHEMA and statement recompilation errors. # proc error_messages_worker {prepare sql schema} { set ret [list] set stmt [$prepare db $sql -1 dummy] execsql $schema lappend ret [sqlite3_step $stmt] lappend ret [sqlite3_errmsg db] lappend ret [sqlite3_finalize $stmt] lappend ret [sqlite3_errmsg db] set ret } proc error_messages_v2 {sql {schema {}}} { error_messages_worker sqlite3_prepare_v2 $sql $schema } proc error_messages {sql {schema {}}} { error_messages_worker sqlite3_prepare $sql $schema } proc sql_error {msg} { error $msg } db func sql_error sql_error #------------------------------------------------------------------------- # Test error messages returned by user-defined SQL functions. # do_test 1.1 { error_messages "SELECT sql_error('custom message')" } [list {*}{ SQLITE_ERROR {SQL logic error or missing database} SQLITE_ERROR {custom message} }] do_test 1.2 { error_messages_v2 "SELECT sql_error('custom message')" } [list {*}{ SQLITE_ERROR {custom message} SQLITE_ERROR {custom message} }] #------------------------------------------------------------------------- # Test error messages generated directly by VDBE code (e.g. constraint # failures). # do_execsql_test 2.1 { CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); INSERT INTO t1 VALUES('abc', 'def'); } do_test 2.2 { error_messages "INSERT INTO t1 VALUES('ghi', 'def')" } [list {*}{ SQLITE_ERROR {SQL logic error or missing database} SQLITE_CONSTRAINT {column b is not unique} }] do_test 2.3 { error_messages_v2 "INSERT INTO t1 VALUES('ghi', 'def')" } [list {*}{ SQLITE_CONSTRAINT {column b is not unique} SQLITE_CONSTRAINT {column b is not unique} }] #------------------------------------------------------------------------- # Test SQLITE_SCHEMA errors. And, for _v2(), test that if the schema # change invalidates the SQL statement itself the error message is returned # correctly. # do_execsql_test 3.1.1 { CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); INSERT INTO t2 VALUES('abc', 'def'); } do_test 3.1.2 { error_messages "SELECT a FROM t2" "DROP TABLE t2" } [list {*}{ SQLITE_ERROR {SQL logic error or missing database} SQLITE_SCHEMA {database schema has changed} }] do_execsql_test 3.2.1 { CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); INSERT INTO t2 VALUES('abc', 'def'); } do_test 3.2.2 { error_messages_v2 "SELECT a FROM t2" "DROP TABLE t2" } [list {*}{ SQLITE_ERROR {no such table: t2} SQLITE_ERROR {no such table: t2} }] finish_test |
Changes to test/fkey_malloc.test.
︙ | ︙ | |||
64 65 66 67 68 69 70 | set rc [catch {db eval $zSql} msg] if {$rc==0} { return $msg } if {[string match {*foreign key*} $msg]} { return "" } | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | set rc [catch {db eval $zSql} msg] if {$rc==0} { return $msg } if {[string match {*foreign key*} $msg]} { return "" } if {$msg eq "out of memory" || $msg eq "constraint failed"} { error 1 } error $msg } do_malloc_test fkey_malloc-4 -sqlprep { PRAGMA foreign_keys = 1; |
︙ | ︙ |
Added test/fts3drop.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | # 2011 October 29 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #************************************************************************* # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS3 module. More specifically, # that DROP TABLE commands can co-exist with savepoints inside transactions. # See ticket [48f299634a] for details. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix fts3drop # If SQLITE_ENABLE_FTS3 is defined, omit this file. ifcapable !fts3 { finish_test return } do_execsql_test 1.1 { CREATE VIRTUAL TABLE f1 USING fts3; INSERT INTO f1 VALUES('a b c'); } do_execsql_test 1.2 { BEGIN; INSERT INTO f1 VALUES('d e f'); SAVEPOINT one; INSERT INTO f1 VALUES('g h i'); DROP TABLE f1; ROLLBACK TO one; COMMIT; } do_execsql_test 1.3 { SELECT * FROM f1; } {{a b c} {d e f}} do_execsql_test 1.4 { BEGIN; INSERT INTO f1 VALUES('g h i'); SAVEPOINT one; INSERT INTO f1 VALUES('j k l'); DROP TABLE f1; RELEASE one; ROLLBACK; } do_execsql_test 1.5 { SELECT * FROM f1; } {{a b c} {d e f}} finish_test |
Changes to test/fts3fault.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | source $testdir/tester.tcl set ::testprefix fts3fault # If SQLITE_ENABLE_FTS3 is not defined, omit this file. ifcapable !fts3 { finish_test ; return } | < < | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | source $testdir/tester.tcl set ::testprefix fts3fault # If SQLITE_ENABLE_FTS3 is not defined, omit this file. ifcapable !fts3 { finish_test ; return } # Test error handling in the sqlite3Fts3Init() function. This is the # function that registers the FTS3 module and various support functions # with SQLite. # do_faultsim_test 1 -body { sqlite3 db test.db expr 0 |
︙ | ︙ | |||
142 143 144 145 146 147 148 | } do_faultsim_test 7.2 -prep { faultsim_delete_and_reopen } -body { execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchinfo=fs3) } } -test { faultsim_test_result {1 {unrecognized matchinfo: fs3}} \ | | > | < | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | } do_faultsim_test 7.2 -prep { faultsim_delete_and_reopen } -body { execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchinfo=fs3) } } -test { faultsim_test_result {1 {unrecognized matchinfo: fs3}} \ {1 {vtable constructor failed: t1}} \ {1 {SQL logic error or missing database}} } do_faultsim_test 7.3 -prep { faultsim_delete_and_reopen } -body { execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchnfo=fts3) } } -test { faultsim_test_result {1 {unrecognized parameter: matchnfo=fts3}} \ {1 {vtable constructor failed: t1}} \ {1 {SQL logic error or missing database}} } proc mit {blob} { set scan(littleEndian) i* set scan(bigEndian) I* binary scan $blob $scan($::tcl_platform(byteOrder)) r return $r |
︙ | ︙ |
Changes to test/fts4content.test.
︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # 4.* - The "INSERT INTO fts(fts) VALUES('rebuild')" command. # # 5.* - Check that CREATE TABLE, DROP TABLE and ALTER TABLE correctly # ignore any %_content table when used with the content=xxx option. # # 6.* - Test the effects of messing with the schema of table xxx after # creating a content=xxx FTS index. # do_execsql_test 1.1.1 { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES('w x', 'x y', 'y z'); CREATE VIRTUAL TABLE ft1 USING fts4(content=t1); } | > > > > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # 4.* - The "INSERT INTO fts(fts) VALUES('rebuild')" command. # # 5.* - Check that CREATE TABLE, DROP TABLE and ALTER TABLE correctly # ignore any %_content table when used with the content=xxx option. # # 6.* - Test the effects of messing with the schema of table xxx after # creating a content=xxx FTS index. # # 7.* - Test that if content=xxx is specified and table xxx does not # exist, the FTS table can still be used for INSERT and some # SELECT statements. # do_execsql_test 1.1.1 { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES('w x', 'x y', 'y z'); CREATE VIRTUAL TABLE ft1 USING fts4(content=t1); } |
︙ | ︙ | |||
471 472 473 474 475 476 477 478 | INSERT INTO ft8(docid, x) VALUES(17, 'I Y T Q O'); } do_execsql_test 7.1.2 { SELECT docid FROM ft8 WHERE ft8 MATCH 'N'; } {13 15} finish_test | > > > > > > > > > > > > > > > > > > > | 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 | INSERT INTO ft8(docid, x) VALUES(17, 'I Y T Q O'); } do_execsql_test 7.1.2 { SELECT docid FROM ft8 WHERE ft8 MATCH 'N'; } {13 15} do_execsql_test 7.2.1 { CREATE VIRTUAL TABLE ft9 USING fts4(content=, x); INSERT INTO ft9(docid, x) VALUES(13, 'U O N X G'); INSERT INTO ft9(docid, x) VALUES(14, 'C J J U B'); INSERT INTO ft9(docid, x) VALUES(15, 'N J Y G X'); INSERT INTO ft9(docid, x) VALUES(16, 'R Y D O R'); INSERT INTO ft9(docid, x) VALUES(17, 'I Y T Q O'); } do_execsql_test 7.2.2 { SELECT docid FROM ft9 WHERE ft9 MATCH 'N'; } {13 15} do_execsql_test 7.2.3 { SELECT name FROM sqlite_master WHERE name LIKE 'ft9_%'; } {ft9_segments ft9_segdir ft9_docsize ft9_stat} do_catchsql_test 7.2.4 { SELECT * FROM ft9 WHERE ft9 MATCH 'N'; } {1 {SQL logic error or missing database}} finish_test |
Changes to test/malloc.test.
︙ | ︙ | |||
863 864 865 866 867 868 869 | execsql {INSERT INTO t1 VALUES(3, 4)} db2 } {} db2 close } catch { db2 close } } | < < < < < < < < < < < < < < < < < < < < < < < < < < | 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | execsql {INSERT INTO t1 VALUES(3, 4)} db2 } {} db2 close } catch { db2 close } } # Test that if an OOM error occurs, aux-data is still correctly destroyed. # This test case was causing either a memory-leak or an assert() failure # at one point, depending on the configuration. # do_malloc_test 39 -tclprep { sqlite3 db test.db |
︙ | ︙ |
Changes to test/vtab1.test.
︙ | ︙ | |||
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 | PRAGMA writable_schema = 1; INSERT INTO sqlite_master VALUES( 'table', 't3', 't3', 0, 'INSERT INTO "%s%s" VALUES(1)' ); } catchsql { CREATE VIRTUAL TABLE t4 USING echo(t3); } } {1 {vtable constructor failed: t4}} unset -nocomplain echo_module_begin_fail finish_test | > > > > > > > > > > > > > > > | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 | PRAGMA writable_schema = 1; INSERT INTO sqlite_master VALUES( 'table', 't3', 't3', 0, 'INSERT INTO "%s%s" VALUES(1)' ); } catchsql { CREATE VIRTUAL TABLE t4 USING echo(t3); } } {1 {vtable constructor failed: t4}} # This test verifies that ticket 48f29963 is fixed. # do_test vtab1-17.1 { execsql { CREATE TABLE t5(a, b); CREATE VIRTUAL TABLE e5 USING echo_v2(t5); BEGIN; INSERT INTO e5 VALUES(1, 2); DROP TABLE e5; SAVEPOINT one; ROLLBACK TO one; COMMIT; } } {} unset -nocomplain echo_module_begin_fail finish_test |