Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Update the built-in SQLite to the latest 3.50.0 beta. Enhancements to the Makefile: add the "env" target. Remove obsolete and/or pointless options. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
f56694fabba628158b472a6f50c46037 |
User & Date: | drh 2025-05-07 14:00:43.602 |
Context
2025-05-08
| ||
12:28 | Minor makefile tweak to make it easier to define the TCL pieces via CLI flags from a docker build. No functional changes. (check-in: dc4319ef47 user: stephan tags: trunk) | |
2025-05-07
| ||
14:00 | Update the built-in SQLite to the latest 3.50.0 beta. Enhancements to the Makefile: add the "env" target. Remove obsolete and/or pointless options. (check-in: f56694fabb user: drh tags: trunk) | |
2025-04-09
| ||
16:15 | Do not allow the content-length to be zero in a redirect. Put in some content, even if it is not used. (check-in: b46ad175c5 user: drh tags: trunk) | |
Changes
Changes to Makefile.
1 2 3 4 | #!/usr/bin/make # # Makefile for wapptclsh on unix. Usage: # | | | < | | > > > > > | 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 | #!/usr/bin/make # # Makefile for wapptclsh on unix. Usage: # # make clean wapptclsh # # You need a static build of TCL9 in the directory that TCLDIR specifies. # To construct such a build: # # (1) Download and untar the TCL9 sources # (2) CD into the unix subdirectory # (3) ./configure --disable-shared --prefix=$HOME/tcl90 # (4) make install # CFLAGS = -Os -static CC = gcc $(CFLAGS) OPTS = TCLDIR ?= $(HOME)/tcl90 TCLLIB = $(TCLDIR)/lib/libtcl9.0.a -lm -lz -lpthread -ldl TCLINC = $(TCLDIR)/include TCLSH = $(TCLDIR)/bin/tclsh9.0 all: wapptclsh wapptclsh: wapptclsh.c $(CC) -I. -I$(TCLINC) -o $@ $(OPTS) wapptclsh.c $(TCLLIB) wapptclsh.c: wapptclsh.c.in wapp.tcl wapptclsh.tcl tclsqlite3.c mkccode.tcl $(TCLSH) mkccode.tcl wapptclsh.c.in >$@ env: @ echo CC = $(CC) @ echo OPTS = $(OPTS) @ echo TCLDIR = $(TCLDIR) clean: rm -f wapptclsh wapptclsh.c |
Changes to tclsqlite3.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in ** 6eb2939a6093c0796910645172d80c530555 with changes in files: ** ** */ #ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE |
︙ | ︙ | |||
449 450 451 452 453 454 455 | ** The SQLITE_VERSION_NUMBER for any given release of SQLite will also ** be larger than the release from which it is derived. Either Y will ** be held constant and Z will be incremented or else Y will be incremented ** and Z will be reset to zero. ** ** Since [version 3.6.18] ([dateof:3.6.18]), ** SQLite source code has been stored in the | | | | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | ** The SQLITE_VERSION_NUMBER for any given release of SQLite will also ** be larger than the release from which it is derived. Either Y will ** be held constant and Z will be incremented or else Y will be incremented ** and Z will be reset to zero. ** ** Since [version 3.6.18] ([dateof:3.6.18]), ** SQLite source code has been stored in the ** <a href="http://fossil-scm.org/">Fossil configuration management ** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID ** string contains the date and time of the check-in (UTC) and a SHA1 ** or SHA3-256 hash of the entire source tree. If the source code has ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.50.0" #define SQLITE_VERSION_NUMBER 3050000 #define SQLITE_SOURCE_ID "2025-05-06 17:56:32 6eb2939a6093c0796910645172d80c53055559dd57c012f1dc815d89fbf84447" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 | ** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]] ** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS ** to block for up to M milliseconds before failing when attempting to ** obtain a file lock using the xLock or xShmLock methods of the VFS. ** The parameter is a pointer to a 32-bit signed integer that contains ** the value that M is to be set to. Before returning, the 32-bit signed ** integer is overwritten with the previous value of M. ** ** <li>[[SQLITE_FCNTL_DATA_VERSION]] ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to ** a database file. The argument is a pointer to a 32-bit unsigned integer. ** The "data version" for the pager is written into the pointer. The ** "data version" changes whenever any change occurs to the corresponding ** database file, either through SQL statements on the same database | > > > > > > | 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 | ** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]] ** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS ** to block for up to M milliseconds before failing when attempting to ** obtain a file lock using the xLock or xShmLock methods of the VFS. ** The parameter is a pointer to a 32-bit signed integer that contains ** the value that M is to be set to. Before returning, the 32-bit signed ** integer is overwritten with the previous value of M. ** ** <li>[[SQLITE_FCNTL_BLOCK_ON_CONNECT]] ** The [SQLITE_FCNTL_BLOCK_ON_CONNECT] opcode is used to configure the ** VFS to block when taking a SHARED lock to connect to a wal mode database. ** This is used to implement the functionality associated with ** SQLITE_SETLK_BLOCK_ON_CONNECT. ** ** <li>[[SQLITE_FCNTL_DATA_VERSION]] ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to ** a database file. The argument is a pointer to a 32-bit unsigned integer. ** The "data version" for the pager is written into the pointer. The ** "data version" changes whenever any change occurs to the corresponding ** database file, either through SQL statements on the same database |
︙ | ︙ | |||
1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 | #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO | > | 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 | #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
︙ | ︙ | |||
3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 | ** was defined (using [sqlite3_busy_handler()]) prior to calling ** this routine, that other busy handler is cleared.)^ ** ** See also: [PRAGMA busy_timeout] */ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 | ** was defined (using [sqlite3_busy_handler()]) prior to calling ** this routine, that other busy handler is cleared.)^ ** ** See also: [PRAGMA busy_timeout] */ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Set the Setlk Timeout ** METHOD: sqlite3 ** ** This routine is only useful in SQLITE_ENABLE_SETLK_TIMEOUT builds. If ** the VFS supports blocking locks, it sets the timeout in ms used by ** eligible locks taken on wal mode databases by the specified database ** handle. In non-SQLITE_ENABLE_SETLK_TIMEOUT builds, or if the VFS does ** not support blocking locks, this function is a no-op. ** ** Passing 0 to this function disables blocking locks altogether. Passing ** -1 to this function requests that the VFS blocks for a long time - ** indefinitely if possible. The results of passing any other negative value ** are undefined. ** ** Internally, each SQLite database handle store two timeout values - the ** busy-timeout (used for rollback mode databases, or if the VFS does not ** support blocking locks) and the setlk-timeout (used for blocking locks ** on wal-mode databases). The sqlite3_busy_timeout() method sets both ** values, this function sets only the setlk-timeout value. Therefore, ** to configure separate busy-timeout and setlk-timeout values for a single ** database handle, call sqlite3_busy_timeout() followed by this function. ** ** Whenever the number of connections to a wal mode database falls from ** 1 to 0, the last connection takes an exclusive lock on the database, ** then checkpoints and deletes the wal file. While it is doing this, any ** new connection that tries to read from the database fails with an ** SQLITE_BUSY error. Or, if the SQLITE_SETLK_BLOCK_ON_CONNECT flag is ** passed to this API, the new connection blocks until the exclusive lock ** has been released. */ SQLITE_API int sqlite3_setlk_timeout(sqlite3*, int ms, int flags); /* ** CAPI3REF: Flags for sqlite3_setlk_timeout() */ #define SQLITE_SETLK_BLOCK_ON_CONNECT 0x01 /* ** CAPI3REF: Convenience Routines For Running Queries ** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** |
︙ | ︙ | |||
5446 5447 5448 5449 5450 5451 5452 | ** more threads at the same moment in time. ** ** For all versions of SQLite up to and including 3.6.23.1, a call to ** [sqlite3_reset()] was required after sqlite3_step() returned anything ** other than [SQLITE_ROW] before any subsequent invocation of ** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from | | | 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 | ** more threads at the same moment in time. ** ** For all versions of SQLite up to and including 3.6.23.1, a call to ** [sqlite3_reset()] was required after sqlite3_step() returned anything ** other than [SQLITE_ROW] before any subsequent invocation of ** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from ** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]), ** sqlite3_step() began ** calling [sqlite3_reset()] automatically in this circumstance rather ** than returning [SQLITE_MISUSE]. This is not considered a compatibility ** break because any application that ever receives an SQLITE_MISUSE error ** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option ** can be used to restore the legacy behavior. ** |
︙ | ︙ | |||
7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 | ** to be invoked whenever a row is updated, inserted or deleted in ** a [rowid table]. ** ^Any callback set by a previous call to this function ** for the same database connection is overridden. ** ** ^The second argument is a pointer to the function to invoke when a ** row is updated, inserted or deleted in a rowid table. ** ^The first argument to the callback is a copy of the third argument ** to sqlite3_update_hook(). ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], ** or [SQLITE_UPDATE], depending on the operation that caused the callback ** to be invoked. ** ^The third and fourth arguments to the callback contain pointers to the ** database and table name containing the affected row. | > > | 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 | ** to be invoked whenever a row is updated, inserted or deleted in ** a [rowid table]. ** ^Any callback set by a previous call to this function ** for the same database connection is overridden. ** ** ^The second argument is a pointer to the function to invoke when a ** row is updated, inserted or deleted in a rowid table. ** ^The update hook is disabled by invoking sqlite3_update_hook() ** with a NULL pointer as the second parameter. ** ^The first argument to the callback is a copy of the third argument ** to sqlite3_update_hook(). ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], ** or [SQLITE_UPDATE], depending on the operation that caused the callback ** to be invoked. ** ^The third and fourth arguments to the callback contain pointers to the ** database and table name containing the affected row. |
︙ | ︙ | |||
11824 11825 11826 11827 11828 11829 11830 | ** When a session object is disabled (see the [sqlite3session_enable()] API), ** it does not accumulate records when rows are inserted, updated or deleted. ** This may appear to have some counter-intuitive effects if a single row ** is written to more than once during a session. For example, if a row ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. | | | | > | 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 | ** When a session object is disabled (see the [sqlite3session_enable()] API), ** it does not accumulate records when rows are inserted, updated or deleted. ** This may appear to have some counter-intuitive effects if a single row ** is written to more than once during a session. For example, if a row ** is inserted while a session object is enabled, then later deleted while ** the same session object is disabled, no INSERT record will appear in the ** changeset, even though the delete took place while the session was disabled. ** Or, if one field of a row is updated while a session is enabled, and ** then another field of the same row is updated while the session is disabled, ** the resulting changeset will contain an UPDATE change that updates both ** fields. */ SQLITE_API int sqlite3session_changeset( sqlite3_session *pSession, /* Session object */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ); |
︙ | ︙ | |||
11898 11899 11900 11901 11902 11903 11904 | ** </ul> ** ** To clarify, if this function is called and then a changeset constructed ** using [sqlite3session_changeset()], then after applying that changeset to ** database zFrom the contents of the two compatible tables would be ** identical. ** | > | | | 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 11957 11958 11959 11960 11961 11962 | ** </ul> ** ** To clarify, if this function is called and then a changeset constructed ** using [sqlite3session_changeset()], then after applying that changeset to ** database zFrom the contents of the two compatible tables would be ** identical. ** ** Unless the call to this function is a no-op as described above, it is an ** error if database zFrom does not exist or does not contain the required ** compatible table. ** ** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg ** may be set to point to a buffer containing an English language error ** message. It is the responsibility of the caller to free this buffer using ** sqlite3_free(). */ |
︙ | ︙ | |||
14096 14097 14098 14099 14100 14101 14102 | ** * Columns in an index ** * Columns in a view ** * Terms in the SET clause of an UPDATE statement ** * Terms in the result set of a SELECT statement ** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. ** * Terms in the VALUES clause of an INSERT statement ** | | > > > > > > | > > | 14145 14146 14147 14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 14171 14172 14173 14174 | ** * Columns in an index ** * Columns in a view ** * Terms in the SET clause of an UPDATE statement ** * Terms in the result set of a SELECT statement ** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement. ** * Terms in the VALUES clause of an INSERT statement ** ** The hard upper limit here is 32767. Most database people will ** tell you that in a well-normalized database, you usually should ** not have more than a dozen or so columns in any table. And if ** that is the case, there is no point in having more than a few ** dozen values in any of the other situations described above. ** ** An index can only have SQLITE_MAX_COLUMN columns from the user ** point of view, but the underlying b-tree that implements the index ** might have up to twice as many columns in a WITHOUT ROWID table, ** since must also store the primary key at the end. Hence the ** column count for Index is u16 instead of i16. */ #if !defined(SQLITE_MAX_COLUMN) # define SQLITE_MAX_COLUMN 2000 #elif SQLITE_MAX_COLUMN>32767 # error SQLITE_MAX_COLUMN may not exceed 32767 #endif /* ** The maximum length of a single SQL statement in bytes. ** ** It used to be the case that setting this value to zero would ** turn the limit off. That is no longer true. It is not possible |
︙ | ︙ | |||
15116 15117 15118 15119 15120 15121 15122 | #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof | | > > > > > > > > > > | 15173 15174 15175 15176 15177 15178 15179 15180 15181 15182 15183 15184 15185 15186 15187 15188 15189 15190 15191 15192 15193 15194 15195 15196 15197 | #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. */ #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) #endif /* ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as ** to avoid complaints from -fsanitize=strict-bounds. */ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY #else # define FLEXARRAY 1 #endif /* ** Macros to compute minimum and maximum of two numbers. */ #ifndef MIN # define MIN(A,B) ((A)<(B)?(A):(B)) |
︙ | ︙ | |||
17351 17352 17353 17354 17355 17356 17357 | SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); #ifdef SQLITE_ENABLE_BYTECODE_VTAB SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); #endif | | | | 17418 17419 17420 17421 17422 17423 17424 17425 17426 17427 17428 17429 17430 17431 17432 17433 | SQLITE_PRIVATE void sqlite3MemSetArrayInt64(sqlite3_value *aMem, int iIdx, i64 val); SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); #ifdef SQLITE_ENABLE_BYTECODE_VTAB SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*); #endif /* Use SQLITE_ENABLE_EXPLAIN_COMMENTS to enable generation of extra ** comments on each VDBE opcode. ** ** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op ** comments in VDBE programs that show key decision points in the code ** generator. */ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); |
︙ | ︙ | |||
18075 18076 18077 18078 18079 18080 18081 18082 18083 18084 18085 18086 18087 18088 | Hash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ Db aDbStatic[2]; /* Static space for the 2 default backends */ Savepoint *pSavepoint; /* List of active savepoints */ int nAnalysisLimit; /* Number of index rows to ANALYZE */ int busyTimeout; /* Busy handler timeout, in msec */ int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ DbClientData *pDbData; /* sqlite3_set_clientdata() content */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY | > > > > | 18142 18143 18144 18145 18146 18147 18148 18149 18150 18151 18152 18153 18154 18155 18156 18157 18158 18159 | Hash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ Db aDbStatic[2]; /* Static space for the 2 default backends */ Savepoint *pSavepoint; /* List of active savepoints */ int nAnalysisLimit; /* Number of index rows to ANALYZE */ int busyTimeout; /* Busy handler timeout, in msec */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT int setlkTimeout; /* Blocking lock timeout, in msec. -1 -> inf. */ int setlkFlags; /* Flags passed to setlk_timeout() */ #endif int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ DbClientData *pDbData; /* sqlite3_set_clientdata() content */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
︙ | ︙ | |||
18887 18888 18889 18890 18891 18892 18893 | /* EV: R-30323-21917 */ u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ Trigger *apTrigger[2];/* Triggers for aAction[] actions */ struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ int iFrom; /* Index of column in pFrom */ char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ | | > > > > | 18958 18959 18960 18961 18962 18963 18964 18965 18966 18967 18968 18969 18970 18971 18972 18973 18974 18975 18976 18977 | /* EV: R-30323-21917 */ u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ Trigger *apTrigger[2];/* Triggers for aAction[] actions */ struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ int iFrom; /* Index of column in pFrom */ char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */ } aCol[FLEXARRAY]; /* One entry for each of nCol columns */ }; /* The size (in bytes) of an FKey object holding N columns. The answer ** does NOT include space to hold the zTo name. */ #define SZ_FKEY(N) (offsetof(FKey,aCol)+(N)*sizeof(struct sColMap)) /* ** SQLite supports many different ways to resolve a constraint ** error. ROLLBACK processing means that a constraint violation ** causes the operation in process to fail and for the current transaction ** to be rolled back. ABORT processing means the operation in process ** fails and any prior changes from that one operation are backed out, |
︙ | ︙ | |||
18951 18952 18953 18954 18955 18956 18957 | struct KeyInfo { u32 nRef; /* Number of references to this KeyInfo object */ u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ u16 nKeyField; /* Number of key columns in the index */ u16 nAllField; /* Total columns, including key plus others */ sqlite3 *db; /* The database connection */ u8 *aSortFlags; /* Sort order for each column. */ | | > > > | 19026 19027 19028 19029 19030 19031 19032 19033 19034 19035 19036 19037 19038 19039 19040 19041 19042 19043 19044 19045 | struct KeyInfo { u32 nRef; /* Number of references to this KeyInfo object */ u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ u16 nKeyField; /* Number of key columns in the index */ u16 nAllField; /* Total columns, including key plus others */ sqlite3 *db; /* The database connection */ u8 *aSortFlags; /* Sort order for each column. */ CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ }; /* The size (in bytes) of a KeyInfo object with up to N fields */ #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) /* ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. */ #define KEYINFO_ORDER_DESC 0x01 /* DESC sort order */ #define KEYINFO_ORDER_BIGNULL 0x02 /* NULL is larger than any other value */ /* |
︙ | ︙ | |||
19073 19074 19075 19076 19077 19078 19079 | u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ const char **azColl; /* Array of collation sequence names for index */ Expr *pPartIdxWhere; /* WHERE clause for partial indices */ ExprList *aColExpr; /* Column expressions */ Pgno tnum; /* DB Page containing root of this index */ LogEst szIdxRow; /* Estimated average row size in bytes */ u16 nKeyCol; /* Number of columns forming the key */ | | > | 19151 19152 19153 19154 19155 19156 19157 19158 19159 19160 19161 19162 19163 19164 19165 19166 19167 19168 19169 19170 19171 19172 19173 19174 19175 19176 19177 | u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ const char **azColl; /* Array of collation sequence names for index */ Expr *pPartIdxWhere; /* WHERE clause for partial indices */ ExprList *aColExpr; /* Column expressions */ Pgno tnum; /* DB Page containing root of this index */ LogEst szIdxRow; /* Estimated average row size in bytes */ u16 nKeyCol; /* Number of columns forming the key */ u16 nColumn; /* Nr columns in btree. Can be 2*Table.nCol */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bIdxRowid:1; /* One or more of the index keys is the ROWID */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ unsigned bHasExpr:1; /* Index contains an expression, either a literal ** expression, or a reference to a VIRTUAL column */ #ifdef SQLITE_ENABLE_STAT4 int nSample; /* Number of elements in aSample[] */ int mxSample; /* Number of slots allocated to aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
︙ | ︙ | |||
19411 19412 19413 19414 19415 19416 19417 | ** upwards into parent nodes. */ #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) /* Macros can be used to test, set, or clear bits in the ** Expr.flags field. */ | | | | | | 19490 19491 19492 19493 19494 19495 19496 19497 19498 19499 19500 19501 19502 19503 19504 19505 19506 19507 | ** upwards into parent nodes. */ #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) /* Macros can be used to test, set, or clear bits in the ** Expr.flags field. */ #define ExprHasProperty(E,P) (((E)->flags&(u32)(P))!=0) #define ExprHasAllProperty(E,P) (((E)->flags&(u32)(P))==(u32)(P)) #define ExprSetProperty(E,P) (E)->flags|=(u32)(P) #define ExprClearProperty(E,P) (E)->flags&=~(u32)(P) #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) #define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) /* Macros used to ensure that the correct members of unions are accessed ** in Expr. */ |
︙ | ︙ | |||
19526 19527 19528 19529 19530 19531 19532 | struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } x; int iConstExprReg; /* Register in which Expr value is cached. Used only ** by Parse.pConstExpr */ } u; | | > > > > > | 19605 19606 19607 19608 19609 19610 19611 19612 19613 19614 19615 19616 19617 19618 19619 19620 19621 19622 19623 19624 19625 | struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } x; int iConstExprReg; /* Register in which Expr value is cached. Used only ** by Parse.pConstExpr */ } u; } a[FLEXARRAY]; /* One slot for each expression in the list */ }; /* The size (in bytes) of an ExprList object that is big enough to hold ** as many as N expressions. */ #define SZ_EXPRLIST(N) \ (offsetof(ExprList,a) + (N)*sizeof(struct ExprList_item)) /* ** Allowed values for Expr.a.eEName */ #define ENAME_NAME 0 /* The AS clause of a result set */ #define ENAME_SPAN 1 /* Complete text of the result set expression */ #define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */ |
︙ | ︙ | |||
19556 19557 19558 19559 19560 19561 19562 | ** ** If "a" is the k-th column of table "t", then IdList.a[0].idx==k. */ struct IdList { int nId; /* Number of identifiers on the list */ struct IdList_item { char *zName; /* Name of the identifier */ | | > > > | 19640 19641 19642 19643 19644 19645 19646 19647 19648 19649 19650 19651 19652 19653 19654 19655 19656 19657 19658 19659 | ** ** If "a" is the k-th column of table "t", then IdList.a[0].idx==k. */ struct IdList { int nId; /* Number of identifiers on the list */ struct IdList_item { char *zName; /* Name of the identifier */ } a[FLEXARRAY]; }; /* The size (in bytes) of an IdList object that can hold up to N IDs. */ #define SZ_IDLIST(N) (offsetof(IdList,a)+(N)*sizeof(struct IdList_item)) /* ** Allowed values for IdList.eType, which determines which value of the a.u4 ** is valid. */ #define EU4_NONE 0 /* Does not use IdList.a.u4 */ #define EU4_IDX 1 /* Uses IdList.a.u4.idx */ #define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ |
︙ | ︙ | |||
19678 19679 19680 19681 19682 19683 19684 | ** This object represents one or more tables that are the source of ** content for an SQL statement. For example, a single SrcList object ** is used to hold the FROM clause of a SELECT statement. SrcList also ** represents the target tables for DELETE, INSERT, and UPDATE statements. ** */ struct SrcList { | | | | > > > > > > > > | 19765 19766 19767 19768 19769 19770 19771 19772 19773 19774 19775 19776 19777 19778 19779 19780 19781 19782 19783 19784 19785 19786 19787 19788 19789 19790 | ** This object represents one or more tables that are the source of ** content for an SQL statement. For example, a single SrcList object ** is used to hold the FROM clause of a SELECT statement. SrcList also ** represents the target tables for DELETE, INSERT, and UPDATE statements. ** */ struct SrcList { int nSrc; /* Number of tables or subqueries in the FROM clause */ u32 nAlloc; /* Number of entries allocated in a[] below */ SrcItem a[FLEXARRAY]; /* One entry for each identifier on the list */ }; /* Size (in bytes) of a SrcList object that can hold as many as N ** SrcItem objects. */ #define SZ_SRCLIST(N) (offsetof(SrcList,a)+(N)*sizeof(SrcItem)) /* Size (in bytes( of a SrcList object that holds 1 SrcItem. This is a ** special case of SZ_SRCITEM(1) that comes up often. */ #define SZ_SRCLIST_1 (offsetof(SrcList,a)+sizeof(SrcItem)) /* ** Permitted values of the SrcList.a.jointype field */ #define JT_INNER 0x01 /* Any kind of inner or cross join */ #define JT_CROSS 0x02 /* Explicit use of the CROSS keyword */ #define JT_NATURAL 0x04 /* True for a "natural" join */ |
︙ | ︙ | |||
20746 20747 20748 20749 20750 20751 20752 | ** An instance of the With object represents a WITH clause containing ** one or more CTEs (common table expressions). */ struct With { int nCte; /* Number of CTEs in the WITH clause */ int bView; /* Belongs to the outermost Select of a view */ With *pOuter; /* Containing WITH clause, or NULL */ | | > > > > | 20841 20842 20843 20844 20845 20846 20847 20848 20849 20850 20851 20852 20853 20854 20855 20856 20857 20858 20859 20860 | ** An instance of the With object represents a WITH clause containing ** one or more CTEs (common table expressions). */ struct With { int nCte; /* Number of CTEs in the WITH clause */ int bView; /* Belongs to the outermost Select of a view */ With *pOuter; /* Containing WITH clause, or NULL */ Cte a[FLEXARRAY]; /* For each CTE in the WITH clause.... */ }; /* The size (in bytes) of a With object that can hold as many ** as N different CTEs. */ #define SZ_WITH(N) (offsetof(With,a) + (N)*sizeof(Cte)) /* ** The Cte object is not guaranteed to persist for the entire duration ** of code generation. (The query flattener or other parser tree ** edits might delete it.) The following object records information ** about each Common Table Expression that must be preserved for the ** duration of the parse. |
︙ | ︙ | |||
20777 20778 20779 20780 20781 20782 20783 | /* Client data associated with sqlite3_set_clientdata() and ** sqlite3_get_clientdata(). */ struct DbClientData { DbClientData *pNext; /* Next in a linked list */ void *pData; /* The data */ void (*xDestructor)(void*); /* Destructor. Might be NULL */ | | > > > > | 20876 20877 20878 20879 20880 20881 20882 20883 20884 20885 20886 20887 20888 20889 20890 20891 20892 20893 20894 20895 | /* Client data associated with sqlite3_set_clientdata() and ** sqlite3_get_clientdata(). */ struct DbClientData { DbClientData *pNext; /* Next in a linked list */ void *pData; /* The data */ void (*xDestructor)(void*); /* Destructor. Might be NULL */ char zName[FLEXARRAY]; /* Name of this client data. MUST BE LAST */ }; /* The size (in bytes) of a DbClientData object that can has a name ** that is N bytes long, including the zero-terminator. */ #define SZ_DBCLIENTDATA(N) (offsetof(DbClientData,zName)+(N)) #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of ** data structures on sqlite3DebugPrintf() using a tree-like view. */ struct TreeView { |
︙ | ︙ | |||
21222 21223 21224 21225 21226 21227 21228 | SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); | | | 21325 21326 21327 21328 21329 21330 21331 21332 21333 21334 21335 21336 21337 21338 21339 | SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int); SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index*, int); #ifdef SQLITE_OMIT_GENERATED_COLUMNS # define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ # define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ #else SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table*, i16); SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table*, i16); #endif |
︙ | ︙ | |||
21320 21321 21322 21323 21324 21325 21326 | SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); | | | 21423 21424 21425 21426 21427 21428 21429 21430 21431 21432 21433 21434 21435 21436 21437 | SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,int,int,char**); SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int, u8); SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); |
︙ | ︙ | |||
21456 21457 21458 21459 21460 21461 21462 | SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,const ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,const SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,const IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int); SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); | | > | 21559 21560 21561 21562 21563 21564 21565 21566 21567 21568 21569 21570 21571 21572 21573 21574 | SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,const ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,const SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,const IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int); SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int); SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3*); #endif |
︙ | ︙ | |||
22556 22557 22558 22559 22560 22561 22562 22563 22564 22565 22566 22567 22568 22569 | "ENABLE_RBU", #endif #ifdef SQLITE_ENABLE_RTREE "ENABLE_RTREE", #endif #ifdef SQLITE_ENABLE_SESSION "ENABLE_SESSION", #endif #ifdef SQLITE_ENABLE_SNAPSHOT "ENABLE_SNAPSHOT", #endif #ifdef SQLITE_ENABLE_SORTER_REFERENCES "ENABLE_SORTER_REFERENCES", #endif | > > > | 22660 22661 22662 22663 22664 22665 22666 22667 22668 22669 22670 22671 22672 22673 22674 22675 22676 | "ENABLE_RBU", #endif #ifdef SQLITE_ENABLE_RTREE "ENABLE_RTREE", #endif #ifdef SQLITE_ENABLE_SESSION "ENABLE_SESSION", #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT "ENABLE_SETLK_TIMEOUT", #endif #ifdef SQLITE_ENABLE_SNAPSHOT "ENABLE_SNAPSHOT", #endif #ifdef SQLITE_ENABLE_SORTER_REFERENCES "ENABLE_SORTER_REFERENCES", #endif |
︙ | ︙ | |||
22611 22612 22613 22614 22615 22616 22617 22618 22619 22620 22621 22622 22623 22624 | #endif #ifdef SQLITE_EXTRA_IFNULLROW "EXTRA_IFNULLROW", #endif #ifdef SQLITE_EXTRA_INIT "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), #endif #ifdef SQLITE_EXTRA_SHUTDOWN "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), #endif #ifdef SQLITE_FTS3_MAX_EXPR_DEPTH "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH), #endif #ifdef SQLITE_FTS5_ENABLE_TEST_MI | > > > | 22718 22719 22720 22721 22722 22723 22724 22725 22726 22727 22728 22729 22730 22731 22732 22733 22734 | #endif #ifdef SQLITE_EXTRA_IFNULLROW "EXTRA_IFNULLROW", #endif #ifdef SQLITE_EXTRA_INIT "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), #endif #ifdef SQLITE_EXTRA_INIT_MUTEXED "EXTRA_INIT_MUTEXED=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT_MUTEXED), #endif #ifdef SQLITE_EXTRA_SHUTDOWN "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), #endif #ifdef SQLITE_FTS3_MAX_EXPR_DEPTH "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH), #endif #ifdef SQLITE_FTS5_ENABLE_TEST_MI |
︙ | ︙ | |||
23595 23596 23597 23598 23599 23600 23601 | u32 payloadSize; /* Total number of bytes in the record */ u32 szRow; /* Byte available in aRow */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ | | < | | > > > > > > > > | 23705 23706 23707 23708 23709 23710 23711 23712 23713 23714 23715 23716 23717 23718 23719 23720 23721 23722 23723 23724 23725 23726 23727 23728 23729 23730 23731 | u32 payloadSize; /* Total number of bytes in the record */ u32 szRow; /* Byte available in aRow */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ /* Space is allocated for aType to hold at least 2*nField+1 entries: ** nField slots for aType[] and nField+1 array slots for aOffset[] */ u32 aType[FLEXARRAY]; /* Type values record decode. MUST BE LAST */ }; /* ** The size (in bytes) of a VdbeCursor object that has an nField value of N ** or less. The value of SZ_VDBECURSOR(n) is guaranteed to be a multiple ** of 8. */ #define SZ_VDBECURSOR(N) \ (ROUND8(offsetof(VdbeCursor,aType)) + ((N)+1)*sizeof(u64)) /* Return true if P is a null-only cursor */ #define IsNullCursor(P) \ ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) /* ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. |
︙ | ︙ | |||
23857 23858 23859 23860 23861 23862 23863 | Mem *pMem; /* Memory cell used to store aggregate context */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ u16 argc; /* Number of arguments */ | | > > > > > > > | 23974 23975 23976 23977 23978 23979 23980 23981 23982 23983 23984 23985 23986 23987 23988 23989 23990 23991 23992 23993 23994 23995 23996 23997 | Mem *pMem; /* Memory cell used to store aggregate context */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ u16 argc; /* Number of arguments */ sqlite3_value *argv[FLEXARRAY]; /* Argument set */ }; /* ** The size (in bytes) of an sqlite3_context object that holds N ** argv[] arguments. */ #define SZ_CONTEXT(N) \ (offsetof(sqlite3_context,argv)+(N)*sizeof(sqlite3_value*)) /* The ScanStatus object holds a single value for the ** sqlite3_stmt_scanstatus() interface. ** ** aAddrRange[]: ** This array is used by ScanStatus elements associated with EQP ** notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is |
︙ | ︙ | |||
23993 23994 23995 23996 23997 23998 23999 | ** sqlite3_preupdate_*() API functions. */ struct PreUpdate { Vdbe *v; VdbeCursor *pCsr; /* Cursor to read old values from */ int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ u8 *aRecord; /* old.* database record */ | | > | 24117 24118 24119 24120 24121 24122 24123 24124 24125 24126 24127 24128 24129 24130 24131 24132 24133 24134 24135 24136 24137 24138 24139 24140 24141 24142 24143 | ** sqlite3_preupdate_*() API functions. */ struct PreUpdate { Vdbe *v; VdbeCursor *pCsr; /* Cursor to read old values from */ int op; /* One of SQLITE_INSERT, UPDATE, DELETE */ u8 *aRecord; /* old.* database record */ KeyInfo *pKeyinfo; /* Key information */ UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ int iNewReg; /* Register for new.* values */ int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ sqlite3_value **apDflt; /* Array of default values, if required */ u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ }; /* ** An instance of this object is used to pass an vector of values into ** OP_VFilter, the xFilter method of a virtual table. The vector is the ** set of values on the right-hand side of an IN constraint. ** |
︙ | ︙ | |||
24371 24372 24373 24374 24375 24376 24377 | SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ u32 nInit = countLookasideSlots(db->lookaside.pInit); u32 nFree = countLookasideSlots(db->lookaside.pFree); #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE nInit += countLookasideSlots(db->lookaside.pSmallInit); nFree += countLookasideSlots(db->lookaside.pSmallFree); #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ | > | | | 24496 24497 24498 24499 24500 24501 24502 24503 24504 24505 24506 24507 24508 24509 24510 24511 24512 | SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ u32 nInit = countLookasideSlots(db->lookaside.pInit); u32 nFree = countLookasideSlots(db->lookaside.pFree); #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE nInit += countLookasideSlots(db->lookaside.pSmallInit); nFree += countLookasideSlots(db->lookaside.pSmallFree); #endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */ assert( db->lookaside.nSlot >= nInit+nFree ); if( pHighwater ) *pHighwater = (int)(db->lookaside.nSlot - nInit); return (int)(db->lookaside.nSlot - (nInit+nFree)); } /* ** Query status information for a single database connection */ SQLITE_API int sqlite3_db_status( sqlite3 *db, /* The database connection whose status is desired */ |
︙ | ︙ | |||
24425 24426 24427 24428 24429 24430 24431 | case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT ); testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); *pCurrent = 0; | | | 24551 24552 24553 24554 24555 24556 24557 24558 24559 24560 24561 24562 24563 24564 24565 | case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT ); testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ); testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ); assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 ); assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 ); *pCurrent = 0; *pHighwater = (int)db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT]; if( resetFlag ){ db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; } break; } /* |
︙ | ︙ | |||
25937 25938 25939 25940 25941 25942 25943 | /* ** Return the number of days after the most recent Sunday. ** ** In other words, return the day of the week according ** to this code: ** | | | 26063 26064 26065 26066 26067 26068 26069 26070 26071 26072 26073 26074 26075 26076 26077 | /* ** Return the number of days after the most recent Sunday. ** ** In other words, return the day of the week according ** to this code: ** ** 0=Sunday, 1=Monday, 2=Tuesday, ..., 6=Saturday */ static int daysAfterSunday(DateTime *pDate){ assert( pDate->validJD ); return (int)((pDate->iJD+129600000)/86400000) % 7; } /* |
︙ | ︙ | |||
30146 30147 30148 30149 30150 30151 30152 30153 30154 30155 30156 30157 30158 30159 | /* ** Include the primary Windows SDK header file. */ #include "windows.h" #ifdef __CYGWIN__ # include <sys/cygwin.h> # include <errno.h> /* amalgamator: dontcache */ #endif /* ** Determine if we are dealing with Windows NT. ** ** We ought to be able to determine if we are compiling for Windows 9x or | > > | 30272 30273 30274 30275 30276 30277 30278 30279 30280 30281 30282 30283 30284 30285 30286 30287 | /* ** Include the primary Windows SDK header file. */ #include "windows.h" #ifdef __CYGWIN__ # include <sys/cygwin.h> # include <sys/stat.h> /* amalgamator: dontcache */ # include <unistd.h> /* amalgamator: dontcache */ # include <errno.h> /* amalgamator: dontcache */ #endif /* ** Determine if we are dealing with Windows NT. ** ** We ought to be able to determine if we are compiling for Windows 9x or |
︙ | ︙ | |||
31540 31541 31542 31543 31544 31545 31546 | #define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ #define etSIZE 4 /* Return number of characters processed so far. %n */ #define etSTRING 5 /* Strings. %s */ #define etDYNSTRING 6 /* Dynamically allocated strings. %z */ #define etPERCENT 7 /* Percent symbol. %% */ #define etCHARX 8 /* Characters. %c */ /* The rest are extensions, not normally found in printf() */ | | | | | | | | | | | | 31668 31669 31670 31671 31672 31673 31674 31675 31676 31677 31678 31679 31680 31681 31682 31683 31684 31685 31686 31687 31688 31689 31690 31691 31692 | #define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */ #define etSIZE 4 /* Return number of characters processed so far. %n */ #define etSTRING 5 /* Strings. %s */ #define etDYNSTRING 6 /* Dynamically allocated strings. %z */ #define etPERCENT 7 /* Percent symbol. %% */ #define etCHARX 8 /* Characters. %c */ /* The rest are extensions, not normally found in printf() */ #define etESCAPE_q 9 /* Strings with '\'' doubled. %q */ #define etESCAPE_Q 10 /* Strings with '\'' doubled and enclosed in '', NULL pointers replaced by SQL NULL. %Q */ #define etTOKEN 11 /* a pointer to a Token structure */ #define etSRCITEM 12 /* a pointer to a SrcItem */ #define etPOINTER 13 /* The %p conversion */ #define etESCAPE_w 14 /* %w -> Strings with '\"' doubled */ #define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ #define etDECIMAL 16 /* %d or %u, but not %x, %o */ #define etINVALID 17 /* Any unrecognized conversion type */ /* ** An "etByte" is an 8-bit unsigned value. */ typedef unsigned char etByte; |
︙ | ︙ | |||
31589 31590 31591 31592 31593 31594 31595 | static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etDECIMAL, 0, 0 }, { 's', 0, 4, etSTRING, 0, 0 }, { 'g', 0, 1, etGENERIC, 30, 0 }, { 'z', 0, 4, etDYNSTRING, 0, 0 }, | | | | | 31717 31718 31719 31720 31721 31722 31723 31724 31725 31726 31727 31728 31729 31730 31731 31732 31733 | static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etDECIMAL, 0, 0 }, { 's', 0, 4, etSTRING, 0, 0 }, { 'g', 0, 1, etGENERIC, 30, 0 }, { 'z', 0, 4, etDYNSTRING, 0, 0 }, { 'q', 0, 4, etESCAPE_q, 0, 0 }, { 'Q', 0, 4, etESCAPE_Q, 0, 0 }, { 'w', 0, 4, etESCAPE_w, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, { 'u', 10, 0, etDECIMAL, 0, 0 }, { 'x', 16, 0, etRADIX, 16, 1 }, { 'X', 16, 0, etRADIX, 0, 4 }, #ifndef SQLITE_OMIT_FLOATING_POINT { 'f', 0, 1, etFLOAT, 0, 0 }, |
︙ | ︙ | |||
32188 32189 32190 32191 32192 32193 32194 | } } }else{ buf[0] = 0; } }else{ unsigned int ch = va_arg(ap,unsigned int); | < < | < < < < < < < < < < < < < < < < | 32316 32317 32318 32319 32320 32321 32322 32323 32324 32325 32326 32327 32328 32329 32330 | } } }else{ buf[0] = 0; } }else{ unsigned int ch = va_arg(ap,unsigned int); length = sqlite3AppendOneUtf8Character(buf, ch); } if( precision>1 ){ i64 nPrior = 1; width -= precision-1; if( width>1 && !flag_leftjustify ){ sqlite3_str_appendchar(pAccum, width-1, ' '); width = 0; |
︙ | ︙ | |||
32286 32287 32288 32289 32290 32291 32292 | adjust_width_for_utf8: if( flag_altform2 && width>0 ){ /* Adjust width to account for extra bytes in UTF-8 characters */ int ii = length - 1; while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; } break; | | | | | < > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | > > > > > > > > | | > > > > > > > > > > > > > > > > | | > | > > > | 32396 32397 32398 32399 32400 32401 32402 32403 32404 32405 32406 32407 32408 32409 32410 32411 32412 32413 32414 32415 32416 32417 32418 32419 32420 32421 32422 32423 32424 32425 32426 32427 32428 32429 32430 32431 32432 32433 32434 32435 32436 32437 32438 32439 32440 32441 32442 32443 32444 32445 32446 32447 32448 32449 32450 32451 32452 32453 32454 32455 32456 32457 32458 32459 32460 32461 32462 32463 32464 32465 32466 32467 32468 32469 32470 32471 32472 32473 32474 32475 32476 32477 32478 32479 32480 32481 32482 32483 32484 32485 32486 32487 32488 32489 32490 32491 32492 32493 32494 32495 32496 32497 32498 32499 32500 32501 32502 32503 32504 32505 32506 32507 32508 32509 32510 32511 32512 32513 | adjust_width_for_utf8: if( flag_altform2 && width>0 ){ /* Adjust width to account for extra bytes in UTF-8 characters */ int ii = length - 1; while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++; } break; case etESCAPE_q: /* %q: Escape ' characters */ case etESCAPE_Q: /* %Q: Escape ' and enclose in '...' */ case etESCAPE_w: { /* %w: Escape " characters */ i64 i, j, k, n; int needQuote = 0; char ch; char *escarg; char q; if( bArgList ){ escarg = getTextArg(pArgList); }else{ escarg = va_arg(ap,char*); } if( escarg==0 ){ escarg = (xtype==etESCAPE_Q ? "NULL" : "(NULL)"); }else if( xtype==etESCAPE_Q ){ needQuote = 1; } if( xtype==etESCAPE_w ){ q = '"'; flag_alternateform = 0; }else{ q = '\''; } /* For %q, %Q, and %w, the precision is the number of bytes (or ** characters if the ! flags is present) to use from the input. ** Because of the extra quoting characters inserted, the number ** of output characters may be larger than the precision. */ k = precision; for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){ if( ch==q ) n++; if( flag_altform2 && (ch&0xc0)==0xc0 ){ while( (escarg[i+1]&0xc0)==0x80 ){ i++; } } } if( flag_alternateform ){ /* For %#q, do unistr()-style backslash escapes for ** all control characters, and for backslash itself. ** For %#Q, do the same but only if there is at least ** one control character. */ u32 nBack = 0; u32 nCtrl = 0; for(k=0; k<i; k++){ if( escarg[k]=='\\' ){ nBack++; }else if( ((u8*)escarg)[k]<=0x1f ){ nCtrl++; } } if( nCtrl || xtype==etESCAPE_q ){ n += nBack + 5*nCtrl; if( xtype==etESCAPE_Q ){ n += 10; needQuote = 2; } }else{ flag_alternateform = 0; } } n += i + 3; if( n>etBUFSIZE ){ bufpt = zExtra = printfTempBuf(pAccum, n); if( bufpt==0 ) return; }else{ bufpt = buf; } j = 0; if( needQuote ){ if( needQuote==2 ){ memcpy(&bufpt[j], "unistr('", 8); j += 8; }else{ bufpt[j++] = '\''; } } k = i; if( flag_alternateform ){ for(i=0; i<k; i++){ bufpt[j++] = ch = escarg[i]; if( ch==q ){ bufpt[j++] = ch; }else if( ch=='\\' ){ bufpt[j++] = '\\'; }else if( ((unsigned char)ch)<=0x1f ){ bufpt[j-1] = '\\'; bufpt[j++] = 'u'; bufpt[j++] = '0'; bufpt[j++] = '0'; bufpt[j++] = ch>=0x10 ? '1' : '0'; bufpt[j++] = "0123456789abcdef"[ch&0xf]; } } }else{ for(i=0; i<k; i++){ bufpt[j++] = ch = escarg[i]; if( ch==q ) bufpt[j++] = ch; } } if( needQuote ){ bufpt[j++] = '\''; if( needQuote==2 ) bufpt[j++] = ')'; } bufpt[j] = 0; length = j; goto adjust_width_for_utf8; } case etTOKEN: { if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; if( flag_alternateform ){ |
︙ | ︙ | |||
32817 32818 32819 32820 32821 32822 32823 32824 32825 32826 32827 32828 32829 32830 32831 32832 32833 32834 32835 32836 32837 32838 32839 | va_start(ap,zFormat); sqlite3_str_vappendf(&acc, zFormat, ap); va_end(ap); zBuf[acc.nChar] = 0; return zBuf; } /* ** This is the routine that actually formats the sqlite3_log() message. ** We house it in a separate routine from sqlite3_log() to avoid using ** stack space on small-stack systems when logging is disabled. ** ** sqlite3_log() must render into a static buffer. It cannot dynamically ** allocate memory because it might be called while the memory allocator ** mutex is held. ** ** sqlite3_str_vappendf() might ask for *temporary* memory allocations for ** certain format characters (%q) or for very large precisions or widths. ** Care must be taken that any sqlite3_log() calls that occur while the ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ | > > > > > > > > > | | 32987 32988 32989 32990 32991 32992 32993 32994 32995 32996 32997 32998 32999 33000 33001 33002 33003 33004 33005 33006 33007 33008 33009 33010 33011 33012 33013 33014 33015 33016 33017 33018 33019 33020 33021 33022 33023 33024 33025 33026 | va_start(ap,zFormat); sqlite3_str_vappendf(&acc, zFormat, ap); va_end(ap); zBuf[acc.nChar] = 0; return zBuf; } /* Maximum size of an sqlite3_log() message. */ #if defined(SQLITE_MAX_LOG_MESSAGE) /* Leave the definition as supplied */ #elif SQLITE_PRINT_BUF_SIZE*10>10000 # define SQLITE_MAX_LOG_MESSAGE 10000 #else # define SQLITE_MAX_LOG_MESSAGE (SQLITE_PRINT_BUF_SIZE*10) #endif /* ** This is the routine that actually formats the sqlite3_log() message. ** We house it in a separate routine from sqlite3_log() to avoid using ** stack space on small-stack systems when logging is disabled. ** ** sqlite3_log() must render into a static buffer. It cannot dynamically ** allocate memory because it might be called while the memory allocator ** mutex is held. ** ** sqlite3_str_vappendf() might ask for *temporary* memory allocations for ** certain format characters (%q) or for very large precisions or widths. ** Care must be taken that any sqlite3_log() calls that occur while the ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_MAX_LOG_MESSAGE]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3_str_vappendf(&acc, zFormat, ap); sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, sqlite3StrAccumFinish(&acc)); } |
︙ | ︙ | |||
34827 34828 34829 34830 34831 34832 34833 34834 34835 34836 34837 34838 34839 34840 | }else{ \ *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ *zOut++ = (u8)(c&0x00FF); \ } \ } /* ** Translate a single UTF-8 character. Return the unicode value. ** ** During translation, assume that the byte that zTerm points ** is a 0x00. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 35006 35007 35008 35009 35010 35011 35012 35013 35014 35015 35016 35017 35018 35019 35020 35021 35022 35023 35024 35025 35026 35027 35028 35029 35030 35031 35032 35033 35034 35035 35036 35037 35038 35039 35040 35041 35042 35043 35044 35045 35046 35047 35048 | }else{ \ *zOut++ = (u8)(0x00D8 + (((c-0x10000)>>18)&0x03)); \ *zOut++ = (u8)(((c>>10)&0x003F) + (((c-0x10000)>>10)&0x00C0)); \ *zOut++ = (u8)(0x00DC + ((c>>8)&0x03)); \ *zOut++ = (u8)(c&0x00FF); \ } \ } /* ** Write a single UTF8 character whose value is v into the ** buffer starting at zOut. zOut must be sized to hold at ** least for bytes. Return the number of bytes needed ** to encode the new character. */ SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char *zOut, u32 v){ if( v<0x00080 ){ zOut[0] = (u8)(v & 0xff); return 1; } if( v<0x00800 ){ zOut[0] = 0xc0 + (u8)((v>>6) & 0x1f); zOut[1] = 0x80 + (u8)(v & 0x3f); return 2; } if( v<0x10000 ){ zOut[0] = 0xe0 + (u8)((v>>12) & 0x0f); zOut[1] = 0x80 + (u8)((v>>6) & 0x3f); zOut[2] = 0x80 + (u8)(v & 0x3f); return 3; } zOut[0] = 0xf0 + (u8)((v>>18) & 0x07); zOut[1] = 0x80 + (u8)((v>>12) & 0x3f); zOut[2] = 0x80 + (u8)((v>>6) & 0x3f); zOut[3] = 0x80 + (u8)(v & 0x3f); return 4; } /* ** Translate a single UTF-8 character. Return the unicode value. ** ** During translation, assume that the byte that zTerm points ** is a 0x00. ** |
︙ | ︙ | |||
35249 35250 35251 35252 35253 35254 35255 | SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ int c; unsigned char const *z = zIn; unsigned char const *zEnd = &z[nByte-1]; int n = 0; if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; | | | 35457 35458 35459 35460 35461 35462 35463 35464 35465 35466 35467 35468 35469 35470 35471 | SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nByte, int nChar){ int c; unsigned char const *z = zIn; unsigned char const *zEnd = &z[nByte-1]; int n = 0; if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++; while( n<nChar && z<=zEnd ){ c = z[0]; z += 2; if( c>=0xd8 && c<0xdc && z<=zEnd && z[0]>=0xdc && z[0]<0xe0 ) z += 2; n++; } return (int)(z-(unsigned char const *)zIn) - (SQLITE_UTF16NATIVE==SQLITE_UTF16LE); |
︙ | ︙ | |||
36933 36934 36935 36936 36937 36938 36939 | } *pA = iA*iB; return 0; #endif } /* | | | 37141 37142 37143 37144 37145 37146 37147 37148 37149 37150 37151 37152 37153 37154 37155 | } *pA = iA*iB; return 0; #endif } /* ** Compute the absolute value of a 32-bit signed integer, if possible. Or ** if the integer has a value of -2147483648, return +2147483647 */ SQLITE_PRIVATE int sqlite3AbsInt32(int x){ if( x>=0 ) return x; if( x==(int)0x80000000 ) return 0x7fffffff; return -x; } |
︙ | ︙ | |||
38910 38911 38912 38913 38914 38915 38916 38917 38918 38919 38920 38921 38922 38923 | int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT unsigned iBusyTimeout; /* Wait this many millisec on locks */ #endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ #endif #ifdef SQLITE_DEBUG /* The next group of variables are used to track whether or not the ** transaction counter in bytes 24-27 of database files are updated | > | 39118 39119 39120 39121 39122 39123 39124 39125 39126 39127 39128 39129 39130 39131 39132 | int openFlags; /* The flags specified at open() */ #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT unsigned iBusyTimeout; /* Wait this many millisec on locks */ int bBlockOnConnect; /* True to block for SHARED locks */ #endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ #endif #ifdef SQLITE_DEBUG /* The next group of variables are used to track whether or not the ** transaction counter in bytes 24-27 of database files are updated |
︙ | ︙ | |||
40303 40304 40305 40306 40307 40308 40309 40310 40311 40312 40313 40314 40315 40316 | if( rc<0 ) return rc; pInode->bProcessLock = 1; pInode->nLock++; }else{ rc = 0; } }else{ rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); } return rc; } /* ** Lock the file with the lock specified by parameter eFileLock - one | > > > > > > > | 40512 40513 40514 40515 40516 40517 40518 40519 40520 40521 40522 40523 40524 40525 40526 40527 40528 40529 40530 40531 40532 | if( rc<0 ) return rc; pInode->bProcessLock = 1; pInode->nLock++; }else{ rc = 0; } }else{ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT if( pFile->bBlockOnConnect && pLock->l_type==F_RDLCK && pLock->l_start==SHARED_FIRST && pLock->l_len==SHARED_SIZE ){ rc = osFcntl(pFile->h, F_SETLKW, pLock); }else #endif rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); } return rc; } /* ** Lock the file with the lock specified by parameter eFileLock - one |
︙ | ︙ | |||
42664 42665 42666 42667 42668 42669 42670 42671 | case SQLITE_FCNTL_HAS_MOVED: { *(int*)pArg = fileHasMoved(pFile); return SQLITE_OK; } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT case SQLITE_FCNTL_LOCK_TIMEOUT: { int iOld = pFile->iBusyTimeout; #if SQLITE_ENABLE_SETLK_TIMEOUT==1 | > | > > > > > | | 42880 42881 42882 42883 42884 42885 42886 42887 42888 42889 42890 42891 42892 42893 42894 42895 42896 42897 42898 42899 42900 42901 42902 42903 42904 42905 42906 42907 42908 42909 42910 | case SQLITE_FCNTL_HAS_MOVED: { *(int*)pArg = fileHasMoved(pFile); return SQLITE_OK; } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT case SQLITE_FCNTL_LOCK_TIMEOUT: { int iOld = pFile->iBusyTimeout; int iNew = *(int*)pArg; #if SQLITE_ENABLE_SETLK_TIMEOUT==1 pFile->iBusyTimeout = iNew<0 ? 0x7FFFFFFF : (unsigned)iNew; #elif SQLITE_ENABLE_SETLK_TIMEOUT==2 pFile->iBusyTimeout = !!(*(int*)pArg); #else # error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" #endif *(int*)pArg = iOld; return SQLITE_OK; } case SQLITE_FCNTL_BLOCK_ON_CONNECT: { int iNew = *(int*)pArg; pFile->bBlockOnConnect = iNew; return SQLITE_OK; } #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; int rc = SQLITE_OK; if( newLimit>sqlite3GlobalConfig.mxMmap ){ newLimit = sqlite3GlobalConfig.mxMmap; } |
︙ | ︙ | |||
43657 43658 43659 43660 43661 43662 43663 | ** ** In other words, if this is a blocking lock, none of the locks that ** occur later in the above list than the lock being obtained may be ** held. ** ** It is not permitted to block on the RECOVER lock. */ | | | 43879 43880 43881 43882 43883 43884 43885 43886 43887 43888 43889 43890 43891 43892 43893 | ** ** In other words, if this is a blocking lock, none of the locks that ** occur later in the above list than the lock being obtained may be ** held. ** ** It is not permitted to block on the RECOVER lock. */ #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) { u16 lockMask = (p->exclMask|p->sharedMask); assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( (ofst!=2) /* not RECOVER */ && (ofst!=1 || lockMask==0 || lockMask==2) && (ofst!=0 || lockMask<3) && (ofst<3 || lockMask<(1<<ofst)) |
︙ | ︙ | |||
45466 45467 45468 45469 45470 45471 45472 | #if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 struct timespec sp; sp.tv_sec = microseconds / 1000000; sp.tv_nsec = (microseconds % 1000000) * 1000; /* Almost all modern unix systems support nanosleep(). But if you are ** compiling for one of the rare exceptions, you can use | | | 45688 45689 45690 45691 45692 45693 45694 45695 45696 45697 45698 45699 45700 45701 45702 | #if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 struct timespec sp; sp.tv_sec = microseconds / 1000000; sp.tv_nsec = (microseconds % 1000000) * 1000; /* Almost all modern unix systems support nanosleep(). But if you are ** compiling for one of the rare exceptions, you can use ** -DHAVE_NANOSLEEP=0 (perhaps in conjunction with -DHAVE_USLEEP if ** usleep() is available) in order to bypass the use of nanosleep() */ nanosleep(&sp, NULL); UNUSED_PARAMETER(NotUsed); return microseconds; #elif defined(HAVE_USLEEP) && HAVE_USLEEP if( microseconds>=1000000 ) sleep(microseconds/1000000); |
︙ | ︙ | |||
47187 47188 47189 47190 47191 47192 47193 47194 47195 47196 47197 47198 47199 47200 47201 | #if SQLITE_MAX_MMAP_SIZE>0 int nFetchOut; /* Number of outstanding xFetch references */ HANDLE hMap; /* Handle for accessing memory mapping */ void *pMapRegion; /* Area memory mapped */ sqlite3_int64 mmapSize; /* Size of mapped region */ sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ #endif }; /* ** The winVfsAppData structure is used for the pAppData member for all of the ** Win32 VFS variants. */ typedef struct winVfsAppData winVfsAppData; struct winVfsAppData { | > > > > > > > > > > | 47409 47410 47411 47412 47413 47414 47415 47416 47417 47418 47419 47420 47421 47422 47423 47424 47425 47426 47427 47428 47429 47430 47431 47432 47433 | #if SQLITE_MAX_MMAP_SIZE>0 int nFetchOut; /* Number of outstanding xFetch references */ HANDLE hMap; /* Handle for accessing memory mapping */ void *pMapRegion; /* Area memory mapped */ sqlite3_int64 mmapSize; /* Size of mapped region */ sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT DWORD iBusyTimeout; /* Wait this many millisec on locks */ int bBlockOnConnect; #endif }; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT # define winFileBusyTimeout(pDbFd) pDbFd->iBusyTimeout #else # define winFileBusyTimeout(pDbFd) 0 #endif /* ** The winVfsAppData structure is used for the pAppData member for all of the ** Win32 VFS variants. */ typedef struct winVfsAppData winVfsAppData; struct winVfsAppData { |
︙ | ︙ | |||
47507 47508 47509 47510 47511 47512 47513 | #if SQLITE_OS_WINCE { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, #else { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, #endif | | | | 47739 47740 47741 47742 47743 47744 47745 47746 47747 47748 47749 47750 47751 47752 47753 47754 47755 47756 47757 47758 47759 47760 47761 47762 | #if SQLITE_OS_WINCE { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 }, #else { "FileTimeToLocalFileTime", (SYSCALL)0, 0 }, #endif #define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(const FILETIME*, \ LPFILETIME))aSyscall[11].pCurrent) #if SQLITE_OS_WINCE { "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 }, #else { "FileTimeToSystemTime", (SYSCALL)0, 0 }, #endif #define osFileTimeToSystemTime ((BOOL(WINAPI*)(const FILETIME*, \ LPSYSTEMTIME))aSyscall[12].pCurrent) { "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 }, #define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent) #if defined(SQLITE_WIN32_HAS_ANSI) |
︙ | ︙ | |||
47622 47623 47624 47625 47626 47627 47628 47629 47630 47631 47632 47633 47634 47635 | #else { "GetFullPathNameW", (SYSCALL)0, 0 }, #endif #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ LPWSTR*))aSyscall[25].pCurrent) { "GetLastError", (SYSCALL)GetLastError, 0 }, #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) #if !defined(SQLITE_OMIT_LOAD_EXTENSION) #if SQLITE_OS_WINCE /* The GetProcAddressA() routine is only available on Windows CE. */ | > > > > > > | 47854 47855 47856 47857 47858 47859 47860 47861 47862 47863 47864 47865 47866 47867 47868 47869 47870 47871 47872 47873 | #else { "GetFullPathNameW", (SYSCALL)0, 0 }, #endif #define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \ LPWSTR*))aSyscall[25].pCurrent) /* ** For GetLastError(), MSDN says: ** ** Minimum supported client: Windows XP [desktop apps | UWP apps] ** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] */ { "GetLastError", (SYSCALL)GetLastError, 0 }, #define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent) #if !defined(SQLITE_OMIT_LOAD_EXTENSION) #if SQLITE_OS_WINCE /* The GetProcAddressA() routine is only available on Windows CE. */ |
︙ | ︙ | |||
47790 47791 47792 47793 47794 47795 47796 | #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT { "LockFile", (SYSCALL)LockFile, 0 }, #else { "LockFile", (SYSCALL)0, 0 }, #endif | | | 48028 48029 48030 48031 48032 48033 48034 48035 48036 48037 48038 48039 48040 48041 48042 | #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT { "LockFile", (SYSCALL)LockFile, 0 }, #else { "LockFile", (SYSCALL)0, 0 }, #endif #if !defined(osLockFile) && defined(SQLITE_WIN32_HAS_ANSI) #define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ DWORD))aSyscall[47].pCurrent) #endif #if !SQLITE_OS_WINCE { "LockFileEx", (SYSCALL)LockFileEx, 0 }, #else |
︙ | ︙ | |||
47854 47855 47856 47857 47858 47859 47860 | { "Sleep", (SYSCALL)0, 0 }, #endif #define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent) { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, | | | | 48092 48093 48094 48095 48096 48097 48098 48099 48100 48101 48102 48103 48104 48105 48106 48107 48108 48109 48110 48111 48112 48113 48114 48115 | { "Sleep", (SYSCALL)0, 0 }, #endif #define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent) { "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 }, #define osSystemTimeToFileTime ((BOOL(WINAPI*)(const SYSTEMTIME*, \ LPFILETIME))aSyscall[56].pCurrent) #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT { "UnlockFile", (SYSCALL)UnlockFile, 0 }, #else { "UnlockFile", (SYSCALL)0, 0 }, #endif #if !defined(osUnlockFile) && defined(SQLITE_WIN32_HAS_ANSI) #define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ DWORD))aSyscall[57].pCurrent) #endif #if !SQLITE_OS_WINCE { "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 }, #else |
︙ | ︙ | |||
47904 47905 47906 47907 47908 47909 47910 | #else { "CreateEventExW", (SYSCALL)0, 0 }, #endif #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ DWORD,DWORD))aSyscall[62].pCurrent) | < > | < > > > > | < | 48142 48143 48144 48145 48146 48147 48148 48149 48150 48151 48152 48153 48154 48155 48156 48157 48158 48159 48160 48161 48162 | #else { "CreateEventExW", (SYSCALL)0, 0 }, #endif #define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \ DWORD,DWORD))aSyscall[62].pCurrent) /* ** For WaitForSingleObject(), MSDN says: ** ** Minimum supported client: Windows XP [desktop apps | UWP apps] ** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] */ { "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 }, #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ DWORD))aSyscall[63].pCurrent) #if !SQLITE_OS_WINCE { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, #else |
︙ | ︙ | |||
48055 48056 48057 48058 48059 48060 48061 48062 48063 48064 48065 48066 48067 48068 | #else { "FlushViewOfFile", (SYSCALL)0, 0 }, #endif #define osFlushViewOfFile \ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) }; /* End of the overrideable system calls */ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "win32" VFSes. Return SQLITE_OK upon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 48295 48296 48297 48298 48299 48300 48301 48302 48303 48304 48305 48306 48307 48308 48309 48310 48311 48312 48313 48314 48315 48316 48317 48318 48319 48320 48321 48322 48323 48324 48325 48326 48327 48328 48329 48330 48331 48332 48333 48334 48335 48336 48337 48338 48339 48340 48341 48342 48343 48344 48345 48346 48347 48348 48349 48350 48351 48352 48353 48354 48355 48356 48357 48358 48359 48360 48361 48362 48363 48364 48365 48366 48367 48368 48369 48370 48371 48372 48373 48374 48375 48376 48377 48378 48379 48380 48381 48382 48383 48384 48385 48386 48387 48388 48389 48390 48391 48392 48393 48394 48395 48396 48397 48398 48399 | #else { "FlushViewOfFile", (SYSCALL)0, 0 }, #endif #define osFlushViewOfFile \ ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent) /* ** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CreateEvent() ** to implement blocking locks with timeouts. MSDN says: ** ** Minimum supported client: Windows XP [desktop apps | UWP apps] ** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT { "CreateEvent", (SYSCALL)CreateEvent, 0 }, #else { "CreateEvent", (SYSCALL)0, 0 }, #endif #define osCreateEvent ( \ (HANDLE(WINAPI*) (LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR)) \ aSyscall[80].pCurrent \ ) /* ** If SQLITE_ENABLE_SETLK_TIMEOUT is defined, we require CancelIo() ** for the case where a timeout expires and a lock request must be ** cancelled. ** ** Minimum supported client: Windows XP [desktop apps | UWP apps] ** Minimum supported server: Windows Server 2003 [desktop apps | UWP apps] */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT { "CancelIo", (SYSCALL)CancelIo, 0 }, #else { "CancelIo", (SYSCALL)0, 0 }, #endif #define osCancelIo ((BOOL(WINAPI*)(HANDLE))aSyscall[81].pCurrent) #if defined(SQLITE_WIN32_HAS_WIDE) && defined(_WIN32) { "GetModuleHandleW", (SYSCALL)GetModuleHandleW, 0 }, #else { "GetModuleHandleW", (SYSCALL)0, 0 }, #endif #define osGetModuleHandleW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[82].pCurrent) #ifndef _WIN32 { "getenv", (SYSCALL)getenv, 0 }, #else { "getenv", (SYSCALL)0, 0 }, #endif #define osGetenv ((const char *(*)(const char *))aSyscall[83].pCurrent) #ifndef _WIN32 { "getcwd", (SYSCALL)getcwd, 0 }, #else { "getcwd", (SYSCALL)0, 0 }, #endif #define osGetcwd ((char*(*)(char*,size_t))aSyscall[84].pCurrent) #ifndef _WIN32 { "readlink", (SYSCALL)readlink, 0 }, #else { "readlink", (SYSCALL)0, 0 }, #endif #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[85].pCurrent) #ifndef _WIN32 { "lstat", (SYSCALL)lstat, 0 }, #else { "lstat", (SYSCALL)0, 0 }, #endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[86].pCurrent) #ifndef _WIN32 { "__errno", (SYSCALL)__errno, 0 }, #else { "__errno", (SYSCALL)0, 0 }, #endif #define osErrno (*((int*(*)(void))aSyscall[87].pCurrent)()) #ifndef _WIN32 { "cygwin_conv_path", (SYSCALL)cygwin_conv_path, 0 }, #else { "cygwin_conv_path", (SYSCALL)0, 0 }, #endif #define osCygwin_conv_path ((size_t(*)(unsigned int, \ const void *, void *, size_t))aSyscall[88].pCurrent) }; /* End of the overrideable system calls */ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "win32" VFSes. Return SQLITE_OK upon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. |
︙ | ︙ | |||
48228 48229 48230 48231 48232 48233 48234 48235 48236 48237 48238 48239 48240 48241 | } sqlite3_mutex_leave(pMem); sqlite3_mutex_leave(pMainMtx); return rc; } #endif /* SQLITE_WIN32_MALLOC */ /* ** This function outputs the specified (ANSI) string to the Win32 debugger ** (if available). */ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE]; | > | 48559 48560 48561 48562 48563 48564 48565 48566 48567 48568 48569 48570 48571 48572 48573 | } sqlite3_mutex_leave(pMem); sqlite3_mutex_leave(pMainMtx); return rc; } #endif /* SQLITE_WIN32_MALLOC */ #ifdef _WIN32 /* ** This function outputs the specified (ANSI) string to the Win32 debugger ** (if available). */ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE]; |
︙ | ︙ | |||
48270 48271 48272 48273 48274 48275 48276 48277 48278 48279 48280 48281 48282 48283 | memcpy(zDbgBuf, zBuf, nMin); fprintf(stderr, "%s", zDbgBuf); }else{ fprintf(stderr, "%s", zBuf); } #endif } /* ** The following routine suspends the current thread for at least ms ** milliseconds. This is equivalent to the Win32 Sleep() interface. */ #if SQLITE_OS_WINRT static HANDLE sleepObj = NULL; | > | 48602 48603 48604 48605 48606 48607 48608 48609 48610 48611 48612 48613 48614 48615 48616 | memcpy(zDbgBuf, zBuf, nMin); fprintf(stderr, "%s", zDbgBuf); }else{ fprintf(stderr, "%s", zBuf); } #endif } #endif /* _WIN32 */ /* ** The following routine suspends the current thread for at least ms ** milliseconds. This is equivalent to the Win32 Sleep() interface. */ #if SQLITE_OS_WINRT static HANDLE sleepObj = NULL; |
︙ | ︙ | |||
48353 48354 48355 48356 48357 48358 48359 | osGetVersionExW(&sInfo); osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); #endif } return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #elif SQLITE_TEST | | > > | 48686 48687 48688 48689 48690 48691 48692 48693 48694 48695 48696 48697 48698 48699 48700 48701 48702 | osGetVersionExW(&sInfo); osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); #endif } return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #elif SQLITE_TEST return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2 || osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ; #else /* ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are ** deprecated are always assumed to be based on the NT kernel. */ return 1; #endif |
︙ | ︙ | |||
48568 48569 48570 48571 48572 48573 48574 48575 48576 48577 48578 48579 48580 48581 | } SQLITE_PRIVATE void sqlite3MemSetDefault(void){ sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); } #endif /* SQLITE_WIN32_MALLOC */ /* ** Convert a UTF-8 string to Microsoft Unicode. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winUtf8ToUnicode(const char *zText){ int nChar; | > | 48903 48904 48905 48906 48907 48908 48909 48910 48911 48912 48913 48914 48915 48916 48917 | } SQLITE_PRIVATE void sqlite3MemSetDefault(void){ sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); } #endif /* SQLITE_WIN32_MALLOC */ #ifdef _WIN32 /* ** Convert a UTF-8 string to Microsoft Unicode. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winUtf8ToUnicode(const char *zText){ int nChar; |
︙ | ︙ | |||
48593 48594 48595 48596 48597 48598 48599 48600 48601 48602 48603 48604 48605 48606 | nChar); if( nChar==0 ){ sqlite3_free(zWideText); zWideText = 0; } return zWideText; } /* ** Convert a Microsoft Unicode string to UTF-8. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUnicodeToUtf8(LPCWSTR zWideText){ | > | 48929 48930 48931 48932 48933 48934 48935 48936 48937 48938 48939 48940 48941 48942 48943 | nChar); if( nChar==0 ){ sqlite3_free(zWideText); zWideText = 0; } return zWideText; } #endif /* _WIN32 */ /* ** Convert a Microsoft Unicode string to UTF-8. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUnicodeToUtf8(LPCWSTR zWideText){ |
︙ | ︙ | |||
48627 48628 48629 48630 48631 48632 48633 | /* ** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM ** code page. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ | | | | | | | | | > | 48964 48965 48966 48967 48968 48969 48970 48971 48972 48973 48974 48975 48976 48977 48978 48979 48980 48981 48982 48983 48984 48985 48986 48987 48988 48989 48990 48991 48992 48993 48994 48995 48996 48997 48998 48999 49000 | /* ** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM ** code page. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ int nWideChar; LPWSTR zMbcsText; int codepage = useAnsi ? CP_ACP : CP_OEMCP; nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, NULL, 0); if( nWideChar==0 ){ return 0; } zMbcsText = sqlite3MallocZero( nWideChar*sizeof(WCHAR) ); if( zMbcsText==0 ){ return 0; } nWideChar = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, nWideChar); if( nWideChar==0 ){ sqlite3_free(zMbcsText); zMbcsText = 0; } return zMbcsText; } #ifdef _WIN32 /* ** Convert a Microsoft Unicode string to a multi-byte character string, ** using the ANSI or OEM code page. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ |
︙ | ︙ | |||
48676 48677 48678 48679 48680 48681 48682 48683 48684 48685 48686 48687 48688 48689 48690 48691 48692 48693 48694 48695 48696 48697 48698 48699 48700 48701 48702 48703 48704 48705 48706 48707 48708 | nByte, 0, 0); if( nByte == 0 ){ sqlite3_free(zText); zText = 0; } return zText; } /* ** Convert a multi-byte character string to UTF-8. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winMbcsToUtf8(const char *zText, int useAnsi){ char *zTextUtf8; LPWSTR zTmpWide; zTmpWide = winMbcsToUnicode(zText, useAnsi); if( zTmpWide==0 ){ return 0; } zTextUtf8 = winUnicodeToUtf8(zTmpWide); sqlite3_free(zTmpWide); return zTextUtf8; } /* ** Convert a UTF-8 string to a multi-byte character string. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUtf8ToMbcs(const char *zText, int useAnsi){ char *zTextMbcs; | > > | 49014 49015 49016 49017 49018 49019 49020 49021 49022 49023 49024 49025 49026 49027 49028 49029 49030 49031 49032 49033 49034 49035 49036 49037 49038 49039 49040 49041 49042 49043 49044 49045 49046 49047 49048 | nByte, 0, 0); if( nByte == 0 ){ sqlite3_free(zText); zText = 0; } return zText; } #endif /* _WIN32 */ /* ** Convert a multi-byte character string to UTF-8. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winMbcsToUtf8(const char *zText, int useAnsi){ char *zTextUtf8; LPWSTR zTmpWide; zTmpWide = winMbcsToUnicode(zText, useAnsi); if( zTmpWide==0 ){ return 0; } zTextUtf8 = winUnicodeToUtf8(zTmpWide); sqlite3_free(zTmpWide); return zTextUtf8; } #ifdef _WIN32 /* ** Convert a UTF-8 string to a multi-byte character string. ** ** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUtf8ToMbcs(const char *zText, int useAnsi){ char *zTextMbcs; |
︙ | ︙ | |||
48744 48745 48746 48747 48748 48749 48750 48751 48752 48753 48754 48755 48756 48757 48758 48759 48760 48761 48762 48763 48764 48765 48766 48767 48768 48769 48770 48771 48772 48773 48774 | } #endif #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return winUnicodeToUtf8(zWideText); } /* ** This is a public wrapper for the winMbcsToUtf8() function. */ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return winMbcsToUtf8(zText, osAreFileApisANSI()); } /* ** This is a public wrapper for the winMbcsToUtf8() function. */ SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; | > > | 49084 49085 49086 49087 49088 49089 49090 49091 49092 49093 49094 49095 49096 49097 49098 49099 49100 49101 49102 49103 49104 49105 49106 49107 49108 49109 49110 49111 49112 49113 49114 49115 49116 | } #endif #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return winUnicodeToUtf8(zWideText); } #endif /* _WIN32 */ /* ** This is a public wrapper for the winMbcsToUtf8() function. */ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif #ifndef SQLITE_OMIT_AUTOINIT if( sqlite3_initialize() ) return 0; #endif return winMbcsToUtf8(zText, osAreFileApisANSI()); } #ifdef _WIN32 /* ** This is a public wrapper for the winMbcsToUtf8() function. */ SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; |
︙ | ︙ | |||
48885 48886 48887 48888 48889 48890 48891 48892 48893 48894 48895 48896 48897 48898 | */ SQLITE_API int sqlite3_win32_set_directory( unsigned long type, /* Identifier for directory being set or reset */ void *zValue /* New value for directory being set or reset */ ){ return sqlite3_win32_set_directory16(type, zValue); } /* ** The return value of winGetLastErrorMsg ** is zero if the error message fits in the buffer, or non-zero ** otherwise (if the message was truncated). */ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ | > | 49227 49228 49229 49230 49231 49232 49233 49234 49235 49236 49237 49238 49239 49240 49241 | */ SQLITE_API int sqlite3_win32_set_directory( unsigned long type, /* Identifier for directory being set or reset */ void *zValue /* New value for directory being set or reset */ ){ return sqlite3_win32_set_directory16(type, zValue); } #endif /* _WIN32 */ /* ** The return value of winGetLastErrorMsg ** is zero if the error message fits in the buffer, or non-zero ** otherwise (if the message was truncated). */ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
︙ | ︙ | |||
49433 49434 49435 49436 49437 49438 49439 49440 49441 49442 49443 49444 49445 49446 49447 49448 49449 49450 49451 49452 | #else if( osIsNT() ){ OVERLAPPED ovlp; memset(&ovlp, 0, sizeof(OVERLAPPED)); ovlp.Offset = offsetLow; ovlp.OffsetHigh = offsetHigh; return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); }else{ return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); } #endif } /* ** Unlock a file region. */ static BOOL winUnlockFile( LPHANDLE phFile, DWORD offsetLow, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 49776 49777 49778 49779 49780 49781 49782 49783 49784 49785 49786 49787 49788 49789 49790 49791 49792 49793 49794 49795 49796 49797 49798 49799 49800 49801 49802 49803 49804 49805 49806 49807 49808 49809 49810 49811 49812 49813 49814 49815 49816 49817 49818 49819 49820 49821 49822 49823 49824 49825 49826 49827 49828 49829 49830 49831 49832 49833 49834 49835 49836 49837 49838 49839 49840 49841 49842 49843 49844 49845 49846 49847 49848 49849 49850 49851 49852 49853 49854 49855 49856 49857 49858 49859 49860 49861 49862 49863 49864 49865 49866 49867 49868 49869 49870 49871 49872 49873 49874 49875 49876 | #else if( osIsNT() ){ OVERLAPPED ovlp; memset(&ovlp, 0, sizeof(OVERLAPPED)); ovlp.Offset = offsetLow; ovlp.OffsetHigh = offsetHigh; return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); #ifdef SQLITE_WIN32_HAS_ANSI }else{ return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); #endif } #endif } /* ** Lock a region of nByte bytes starting at offset offset of file hFile. ** Take an EXCLUSIVE lock if parameter bExclusive is true, or a SHARED lock ** otherwise. If nMs is greater than zero and the lock cannot be obtained ** immediately, block for that many ms before giving up. ** ** This function returns SQLITE_OK if the lock is obtained successfully. If ** some other process holds the lock, SQLITE_BUSY is returned if nMs==0, or ** SQLITE_BUSY_TIMEOUT otherwise. Or, if an error occurs, SQLITE_IOERR. */ static int winHandleLockTimeout( HANDLE hFile, DWORD offset, DWORD nByte, int bExcl, DWORD nMs ){ DWORD flags = LOCKFILE_FAIL_IMMEDIATELY | (bExcl?LOCKFILE_EXCLUSIVE_LOCK:0); int rc = SQLITE_OK; BOOL ret; if( !osIsNT() ){ ret = winLockFile(&hFile, flags, offset, 0, nByte, 0); }else{ OVERLAPPED ovlp; memset(&ovlp, 0, sizeof(OVERLAPPED)); ovlp.Offset = offset; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT if( nMs!=0 ){ flags &= ~LOCKFILE_FAIL_IMMEDIATELY; } ovlp.hEvent = osCreateEvent(NULL, TRUE, FALSE, NULL); if( ovlp.hEvent==NULL ){ return SQLITE_IOERR_LOCK; } #endif ret = osLockFileEx(hFile, flags, 0, nByte, 0, &ovlp); #ifdef SQLITE_ENABLE_SETLK_TIMEOUT /* If SQLITE_ENABLE_SETLK_TIMEOUT is defined, then the file-handle was ** opened with FILE_FLAG_OVERHEAD specified. In this case, the call to ** LockFileEx() may fail because the request is still pending. This can ** happen even if LOCKFILE_FAIL_IMMEDIATELY was specified. ** ** If nMs is 0, then LOCKFILE_FAIL_IMMEDIATELY was set in the flags ** passed to LockFileEx(). In this case, if the operation is pending, ** block indefinitely until it is finished. ** ** Otherwise, wait for up to nMs ms for the operation to finish. nMs ** may be set to INFINITE. */ if( !ret && GetLastError()==ERROR_IO_PENDING ){ DWORD nDelay = (nMs==0 ? INFINITE : nMs); DWORD res = osWaitForSingleObject(ovlp.hEvent, nDelay); if( res==WAIT_OBJECT_0 ){ ret = TRUE; }else if( res==WAIT_TIMEOUT ){ rc = SQLITE_BUSY_TIMEOUT; }else{ /* Some other error has occurred */ rc = SQLITE_IOERR_LOCK; } /* If it is still pending, cancel the LockFileEx() call. */ osCancelIo(hFile); } osCloseHandle(ovlp.hEvent); #endif } if( rc==SQLITE_OK && !ret ){ rc = SQLITE_BUSY; } return rc; } /* ** Unlock a file region. */ static BOOL winUnlockFile( LPHANDLE phFile, DWORD offsetLow, |
︙ | ︙ | |||
49464 49465 49466 49467 49468 49469 49470 49471 49472 49473 49474 49475 49476 49477 49478 49479 49480 49481 49482 49483 49484 49485 49486 49487 49488 49489 49490 | #else if( osIsNT() ){ OVERLAPPED ovlp; memset(&ovlp, 0, sizeof(OVERLAPPED)); ovlp.Offset = offsetLow; ovlp.OffsetHigh = offsetHigh; return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); }else{ return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); } #endif } /***************************************************************************** ** The next group of routines implement the I/O methods specified ** by the sqlite3_io_methods object. ******************************************************************************/ /* ** Some Microsoft compilers lack this definition. */ #ifndef INVALID_SET_FILE_POINTER # define INVALID_SET_FILE_POINTER ((DWORD)-1) #endif /* | > > > > > > > > > > | > | < > | > > < < < > > | < < < | | | | < < < | | < < < | < < | < | > > | | | | > > > > > > > | > > > > > | < > | 49888 49889 49890 49891 49892 49893 49894 49895 49896 49897 49898 49899 49900 49901 49902 49903 49904 49905 49906 49907 49908 49909 49910 49911 49912 49913 49914 49915 49916 49917 49918 49919 49920 49921 49922 49923 49924 49925 49926 49927 49928 49929 49930 49931 49932 49933 49934 49935 49936 49937 49938 49939 49940 49941 49942 49943 49944 49945 49946 49947 49948 49949 49950 49951 49952 49953 49954 49955 49956 49957 49958 49959 49960 49961 49962 49963 49964 49965 49966 49967 49968 49969 49970 49971 49972 49973 49974 49975 49976 49977 49978 49979 49980 49981 49982 49983 49984 49985 49986 49987 49988 49989 49990 49991 49992 49993 49994 | #else if( osIsNT() ){ OVERLAPPED ovlp; memset(&ovlp, 0, sizeof(OVERLAPPED)); ovlp.Offset = offsetLow; ovlp.OffsetHigh = offsetHigh; return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); #ifdef SQLITE_WIN32_HAS_ANSI }else{ return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow, numBytesHigh); #endif } #endif } /* ** Remove an nByte lock starting at offset iOff from HANDLE h. */ static int winHandleUnlock(HANDLE h, int iOff, int nByte){ BOOL ret = winUnlockFile(&h, iOff, 0, nByte, 0); return (ret ? SQLITE_OK : SQLITE_IOERR_UNLOCK); } /***************************************************************************** ** The next group of routines implement the I/O methods specified ** by the sqlite3_io_methods object. ******************************************************************************/ /* ** Some Microsoft compilers lack this definition. */ #ifndef INVALID_SET_FILE_POINTER # define INVALID_SET_FILE_POINTER ((DWORD)-1) #endif /* ** Seek the file handle h to offset nByte of the file. ** ** If successful, return SQLITE_OK. Or, if an error occurs, return an SQLite ** error code. */ static int winHandleSeek(HANDLE h, sqlite3_int64 iOffset){ int rc = SQLITE_OK; /* Return value */ #if !SQLITE_OS_WINRT LONG upperBits; /* Most sig. 32 bits of new offset */ LONG lowerBits; /* Least sig. 32 bits of new offset */ DWORD dwRet; /* Value returned by SetFilePointer() */ upperBits = (LONG)((iOffset>>32) & 0x7fffffff); lowerBits = (LONG)(iOffset & 0xffffffff); dwRet = osSetFilePointer(h, lowerBits, &upperBits, FILE_BEGIN); /* API oddity: If successful, SetFilePointer() returns a dword ** containing the lower 32-bits of the new file-offset. Or, if it fails, ** it returns INVALID_SET_FILE_POINTER. However according to MSDN, ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine ** whether an error has actually occurred, it is also necessary to call ** GetLastError(). */ if( dwRet==INVALID_SET_FILE_POINTER ){ DWORD lastErrno = osGetLastError(); if( lastErrno!=NO_ERROR ){ rc = SQLITE_IOERR_SEEK; } } #else /* This implementation works for WinRT. */ LARGE_INTEGER x; /* The new offset */ BOOL bRet; /* Value returned by SetFilePointerEx() */ x.QuadPart = iOffset; bRet = osSetFilePointerEx(h, x, 0, FILE_BEGIN); if(!bRet){ rc = SQLITE_IOERR_SEEK; } #endif OSTRACE(("SEEK file=%p, offset=%lld rc=%s\n", h, iOffset, sqlite3ErrName(rc))); return rc; } /* ** Move the current position of the file handle passed as the first ** argument to offset iOffset within the file. If successful, return 0. ** Otherwise, set pFile->lastErrno and return non-zero. */ static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ int rc; rc = winHandleSeek(pFile->h, iOffset); if( rc!=SQLITE_OK ){ pFile->lastErrno = osGetLastError(); winLogError(rc, pFile->lastErrno, "winSeekFile", pFile->zPath); } return rc; } #if SQLITE_MAX_MMAP_SIZE>0 /* Forward references to VFS helper methods used for memory mapped files */ static int winMapfile(winFile*, sqlite3_int64); static int winUnmapfile(winFile*); #endif |
︙ | ︙ | |||
49802 49803 49804 49805 49806 49807 49808 49809 49810 49811 49812 49813 49814 49815 | }else{ winLogIoerr(nRetry, __LINE__); } OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; } /* ** Truncate an open file to a specified size */ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ winFile *pFile = (winFile*)id; /* File handle object */ int rc = SQLITE_OK; /* Return code for this function */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 50240 50241 50242 50243 50244 50245 50246 50247 50248 50249 50250 50251 50252 50253 50254 50255 50256 50257 50258 50259 50260 50261 50262 50263 50264 50265 50266 50267 50268 50269 50270 50271 50272 50273 50274 50275 50276 50277 50278 50279 50280 50281 50282 50283 50284 50285 50286 50287 50288 50289 50290 50291 50292 50293 50294 50295 50296 50297 50298 50299 50300 50301 50302 50303 50304 50305 50306 50307 | }else{ winLogIoerr(nRetry, __LINE__); } OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n", osGetCurrentProcessId(), pFile, pFile->h)); return SQLITE_OK; } /* ** Truncate the file opened by handle h to nByte bytes in size. */ static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){ int rc = SQLITE_OK; /* Return code */ rc = winHandleSeek(h, nByte); if( rc==SQLITE_OK ){ if( 0==osSetEndOfFile(h) ){ rc = SQLITE_IOERR_TRUNCATE; } } return rc; } /* ** Determine the size in bytes of the file opened by the handle passed as ** the first argument. */ static int winHandleSize(HANDLE h, sqlite3_int64 *pnByte){ int rc = SQLITE_OK; #if SQLITE_OS_WINRT FILE_STANDARD_INFO info; BOOL b; b = osGetFileInformationByHandleEx(h, FileStandardInfo, &info, sizeof(info)); if( b ){ *pnByte = info.EndOfFile.QuadPart; }else{ rc = SQLITE_IOERR_FSTAT; } #else DWORD upperBits = 0; DWORD lowerBits = 0; assert( pnByte ); lowerBits = osGetFileSize(h, &upperBits); *pnByte = (((sqlite3_int64)upperBits)<<32) + lowerBits; if( lowerBits==INVALID_FILE_SIZE && osGetLastError()!=NO_ERROR ){ rc = SQLITE_IOERR_FSTAT; } #endif return rc; } /* ** Close the handle passed as the only argument. */ static void winHandleClose(HANDLE h){ if( h!=INVALID_HANDLE_VALUE ){ osCloseHandle(h); } } /* ** Truncate an open file to a specified size */ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ winFile *pFile = (winFile*)id; /* File handle object */ int rc = SQLITE_OK; /* Return code for this function */ |
︙ | ︙ | |||
50058 50059 50060 50061 50062 50063 50064 | #endif /* ** Acquire a reader lock. ** Different API routines are called depending on whether or not this ** is Win9x or WinNT. */ | | > | | | 50550 50551 50552 50553 50554 50555 50556 50557 50558 50559 50560 50561 50562 50563 50564 50565 50566 50567 50568 50569 50570 50571 50572 50573 50574 50575 50576 50577 50578 50579 50580 50581 50582 50583 50584 50585 | #endif /* ** Acquire a reader lock. ** Different API routines are called depending on whether or not this ** is Win9x or WinNT. */ static int winGetReadLock(winFile *pFile, int bBlock){ int res; DWORD mask = ~(bBlock ? LOCKFILE_FAIL_IMMEDIATELY : 0); OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); if( osIsNT() ){ #if SQLITE_OS_WINCE /* ** NOTE: Windows CE is handled differently here due its lack of the Win32 ** API LockFileEx. */ res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0); #else res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS&mask, SHARED_FIRST, 0, SHARED_SIZE, 0); #endif } #ifdef SQLITE_WIN32_HAS_ANSI else{ int lk; sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS&mask, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); } #endif if( res == 0 ){ pFile->lastErrno = osGetLastError(); /* No need to log a failure to lock */ } |
︙ | ︙ | |||
50173 50174 50175 50176 50177 50178 50179 | /* Make sure the locking sequence is correct */ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); | | | | | > > > > > > > | > | > > | | > > | > > > | < < < > | > > > | 50666 50667 50668 50669 50670 50671 50672 50673 50674 50675 50676 50677 50678 50679 50680 50681 50682 50683 50684 50685 50686 50687 50688 50689 50690 50691 50692 50693 50694 50695 50696 50697 50698 50699 50700 50701 50702 50703 50704 50705 50706 50707 50708 50709 50710 50711 50712 50713 50714 50715 50716 50717 50718 50719 50720 50721 50722 50723 50724 50725 50726 50727 50728 50729 50730 50731 50732 50733 50734 50735 | /* Make sure the locking sequence is correct */ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK ); /* Lock the PENDING_LOCK byte if we need to acquire an EXCLUSIVE lock or ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of ** the PENDING_LOCK byte is temporary. */ newLocktype = pFile->locktype; if( locktype==SHARED_LOCK || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) ){ int cnt = 3; /* Flags for the LockFileEx() call. This should be an exclusive lock if ** this call is to obtain EXCLUSIVE, or a shared lock if this call is to ** obtain SHARED. */ int flags = LOCKFILE_FAIL_IMMEDIATELY; if( locktype==EXCLUSIVE_LOCK ){ flags |= LOCKFILE_EXCLUSIVE_LOCK; } while( cnt>0 ){ /* Try 3 times to get the pending lock. This is needed to work ** around problems caused by indexing and/or anti-virus software on ** Windows systems. ** ** If you are using this code as a model for alternative VFSes, do not ** copy this retry logic. It is a hack intended for Windows only. */ res = winLockFile(&pFile->h, flags, PENDING_BYTE, 0, 1, 0); if( res ) break; lastErrno = osGetLastError(); OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n", pFile->h, cnt, res )); if( lastErrno==ERROR_INVALID_HANDLE ){ pFile->lastErrno = lastErrno; rc = SQLITE_IOERR_LOCK; OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", pFile->h, cnt, sqlite3ErrName(rc) )); return rc; } cnt--; if( cnt>0 ) sqlite3_win32_sleep(1); } gotPendingLock = res; } /* Acquire a shared lock */ if( locktype==SHARED_LOCK && res ){ assert( pFile->locktype==NO_LOCK ); #ifdef SQLITE_ENABLE_SETLK_TIMEOUT res = winGetReadLock(pFile, pFile->bBlockOnConnect); #else res = winGetReadLock(pFile, 0); #endif if( res ){ newLocktype = SHARED_LOCK; }else{ lastErrno = osGetLastError(); } } |
︙ | ︙ | |||
50250 50251 50252 50253 50254 50255 50256 | (void)winUnlockReadLock(pFile); res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ lastErrno = osGetLastError(); | | | 50759 50760 50761 50762 50763 50764 50765 50766 50767 50768 50769 50770 50771 50772 50773 | (void)winUnlockReadLock(pFile); res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ lastErrno = osGetLastError(); winGetReadLock(pFile, 0); } } /* If we are holding a PENDING lock that ought to be released, then ** release it now. */ if( gotPendingLock && locktype==SHARED_LOCK ){ |
︙ | ︙ | |||
50330 50331 50332 50333 50334 50335 50336 | assert( pFile!=0 ); assert( locktype<=SHARED_LOCK ); OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); | | | 50839 50840 50841 50842 50843 50844 50845 50846 50847 50848 50849 50850 50851 50852 50853 | assert( pFile!=0 ); assert( locktype<=SHARED_LOCK ); OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); type = pFile->locktype; if( type>=EXCLUSIVE_LOCK ){ winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( locktype==SHARED_LOCK && !winGetReadLock(pFile, 0) ){ /* This should never happen. We should always be able to ** reacquire the read lock */ rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), "winUnlock", pFile->zPath); } } if( type>=RESERVED_LOCK ){ |
︙ | ︙ | |||
50540 50541 50542 50543 50544 50545 50546 50547 50548 50549 50550 50551 50552 50553 | rc = winMapfile(pFile, -1); } } OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); return rc; } #endif } OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); return SQLITE_NOTFOUND; } /* ** Return the sector size in bytes of the underlying block device for | > > > > > > > > > > > > > > > > > > > > > > | 51049 51050 51051 51052 51053 51054 51055 51056 51057 51058 51059 51060 51061 51062 51063 51064 51065 51066 51067 51068 51069 51070 51071 51072 51073 51074 51075 51076 51077 51078 51079 51080 51081 51082 51083 51084 | rc = winMapfile(pFile, -1); } } OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); return rc; } #endif #ifdef SQLITE_ENABLE_SETLK_TIMEOUT case SQLITE_FCNTL_LOCK_TIMEOUT: { int iOld = pFile->iBusyTimeout; int iNew = *(int*)pArg; #if SQLITE_ENABLE_SETLK_TIMEOUT==1 pFile->iBusyTimeout = (iNew < 0) ? INFINITE : (DWORD)iNew; #elif SQLITE_ENABLE_SETLK_TIMEOUT==2 pFile->iBusyTimeout = (DWORD)(!!iNew); #else # error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" #endif *(int*)pArg = iOld; return SQLITE_OK; } case SQLITE_FCNTL_BLOCK_ON_CONNECT: { int iNew = *(int*)pArg; pFile->bBlockOnConnect = iNew; return SQLITE_OK; } #endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ } OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); return SQLITE_NOTFOUND; } /* ** Return the sector size in bytes of the underlying block device for |
︙ | ︙ | |||
50620 50621 50622 50623 50624 50625 50626 | ** this object or while reading or writing the following fields: ** ** nRef ** pNext ** ** The following fields are read-only after the object is created: ** | < > > > > > | > > < < < | < < < < < | < < < < < > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 51151 51152 51153 51154 51155 51156 51157 51158 51159 51160 51161 51162 51163 51164 51165 51166 51167 51168 51169 51170 51171 51172 51173 51174 51175 51176 51177 51178 51179 51180 51181 51182 51183 51184 51185 51186 51187 51188 51189 51190 51191 51192 51193 51194 51195 51196 51197 51198 51199 51200 51201 51202 51203 51204 51205 51206 51207 51208 51209 51210 51211 51212 51213 51214 51215 51216 51217 51218 51219 51220 51221 51222 51223 51224 51225 51226 51227 51228 | ** this object or while reading or writing the following fields: ** ** nRef ** pNext ** ** The following fields are read-only after the object is created: ** ** zFilename ** ** Either winShmNode.mutex must be held or winShmNode.nRef==0 and ** winShmMutexHeld() is true when reading or writing any other field ** in this structure. ** ** File-handle hSharedShm is used to (a) take the DMS lock, (b) truncate ** the *-shm file if the DMS-locking protocol demands it, and (c) map ** regions of the *-shm file into memory using MapViewOfFile() or ** similar. Other locks are taken by individual clients using the ** winShm.hShm handles. */ struct winShmNode { sqlite3_mutex *mutex; /* Mutex to access this object */ char *zFilename; /* Name of the file */ HANDLE hSharedShm; /* File handle open on zFilename */ int isUnlocked; /* DMS lock has not yet been obtained */ int isReadonly; /* True if read-only */ int szRegion; /* Size of shared-memory regions */ int nRegion; /* Size of array apRegion */ struct ShmRegion { HANDLE hMap; /* File handle from CreateFileMapping */ void *pMap; } *aRegion; DWORD lastErrno; /* The Windows errno from the last I/O error */ int nRef; /* Number of winShm objects pointing to this */ winShmNode *pNext; /* Next in list of all winShmNode objects */ #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) u8 nextShmId; /* Next available winShm.id value */ #endif }; /* ** A global array of all winShmNode objects. ** ** The winShmMutexHeld() must be true while reading or writing this list. */ static winShmNode *winShmNodeList = 0; /* ** Structure used internally by this VFS to record the state of an ** open shared memory connection. There is one such structure for each ** winFile open on a wal mode database. */ struct winShm { winShmNode *pShmNode; /* The underlying winShmNode object */ u16 sharedMask; /* Mask of shared locks held */ u16 exclMask; /* Mask of exclusive locks held */ HANDLE hShm; /* File-handle on *-shm file. For locking. */ int bReadonly; /* True if hShm is opened read-only */ #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) u8 id; /* Id of this connection with its winShmNode */ #endif }; /* ** Constants used for locking */ #define WIN_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ #define WIN_SHM_DMS (WIN_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ /* Forward references to VFS methods */ static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); static int winDelete(sqlite3_vfs *,const char*,int); /* ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. ** |
︙ | ︙ | |||
50764 50765 50766 50767 50768 50769 50770 | osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); UNUSED_VARIABLE_VALUE(bRc); bRc = osCloseHandle(p->aRegion[i].hMap); OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); UNUSED_VARIABLE_VALUE(bRc); } | < < | < < | > | < < < < < | > | > > > > > > > > > > > > > > > > > > > > | > > | | > | | > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | > > > > | > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > | > > > | > > > > > | > > > > > > | | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > < < < < | < > > > > > > > > | < | < | < < < < < < < < < > | < < | | > > > > > > | | > > | > > > < < | | < < < | < | < | < < > | > | > | < | > | > | < < < < < < < < < < < < < < | | < < < | > | < < < < < < < | | | < > > > < | > > > | | < | > > > | > > > > | < < < | < < | > | | < < < < > > | < | < < | < < | > > | | < | > > | | > | < < | < > > < | < < | < | > > > | > | | > | | | < | < > | < | | > | > | | < < < < < < < < | | | < > | > > | | > | 51246 51247 51248 51249 51250 51251 51252 51253 51254 51255 51256 51257 51258 51259 51260 51261 51262 51263 51264 51265 51266 51267 51268 51269 51270 51271 51272 51273 51274 51275 51276 51277 51278 51279 51280 51281 51282 51283 51284 51285 51286 51287 51288 51289 51290 51291 51292 51293 51294 51295 51296 51297 51298 51299 51300 51301 51302 51303 51304 51305 51306 51307 51308 51309 51310 51311 51312 51313 51314 51315 51316 51317 51318 51319 51320 51321 51322 51323 51324 51325 51326 51327 51328 51329 51330 51331 51332 51333 51334 51335 51336 51337 51338 51339 51340 51341 51342 51343 51344 51345 51346 51347 51348 51349 51350 51351 51352 51353 51354 51355 51356 51357 51358 51359 51360 51361 51362 51363 51364 51365 51366 51367 51368 51369 51370 51371 51372 51373 51374 51375 51376 51377 51378 51379 51380 51381 51382 51383 51384 51385 51386 51387 51388 51389 51390 51391 51392 51393 51394 51395 51396 51397 51398 51399 51400 51401 51402 51403 51404 51405 51406 51407 51408 51409 51410 51411 51412 51413 51414 51415 51416 51417 51418 51419 51420 51421 51422 51423 51424 51425 51426 51427 51428 51429 51430 51431 51432 51433 51434 51435 51436 51437 51438 51439 51440 51441 51442 51443 51444 51445 51446 51447 51448 51449 51450 51451 51452 51453 51454 51455 51456 51457 51458 51459 51460 51461 51462 51463 51464 51465 51466 51467 51468 51469 51470 51471 51472 51473 51474 51475 51476 51477 51478 51479 51480 51481 51482 51483 51484 51485 51486 51487 51488 51489 51490 51491 51492 51493 51494 51495 51496 51497 51498 51499 51500 51501 51502 51503 51504 51505 51506 51507 51508 51509 51510 51511 51512 51513 51514 51515 51516 51517 51518 51519 51520 51521 51522 51523 51524 51525 51526 51527 51528 51529 51530 51531 51532 51533 51534 51535 51536 51537 51538 51539 51540 51541 51542 51543 51544 51545 51546 51547 51548 51549 51550 51551 51552 51553 51554 51555 51556 51557 51558 51559 51560 51561 51562 51563 51564 51565 51566 51567 51568 51569 51570 51571 51572 51573 51574 51575 51576 51577 51578 51579 51580 51581 51582 51583 51584 51585 51586 51587 51588 51589 51590 51591 51592 51593 51594 51595 51596 51597 51598 51599 51600 51601 51602 51603 51604 51605 51606 51607 51608 51609 51610 51611 51612 51613 51614 51615 51616 51617 51618 51619 51620 51621 51622 51623 51624 51625 51626 51627 51628 51629 51630 51631 51632 51633 51634 51635 51636 51637 51638 51639 51640 51641 51642 51643 51644 51645 51646 51647 51648 51649 51650 51651 51652 51653 51654 51655 51656 51657 51658 51659 51660 51661 51662 51663 51664 51665 51666 51667 51668 51669 51670 51671 51672 51673 51674 51675 51676 51677 51678 51679 51680 51681 51682 51683 51684 51685 51686 51687 51688 51689 51690 51691 51692 51693 51694 51695 51696 51697 51698 51699 51700 51701 51702 51703 51704 51705 51706 51707 51708 51709 51710 51711 51712 51713 51714 51715 51716 51717 51718 51719 51720 51721 51722 51723 51724 51725 51726 51727 51728 51729 51730 51731 51732 51733 51734 51735 51736 51737 51738 51739 51740 51741 | osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); UNUSED_VARIABLE_VALUE(bRc); bRc = osCloseHandle(p->aRegion[i].hMap); OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); UNUSED_VARIABLE_VALUE(bRc); } winHandleClose(p->hSharedShm); if( deleteFlag ){ SimulateIOErrorBenign(1); sqlite3BeginBenignMalloc(); winDelete(pVfs, p->zFilename, 0); sqlite3EndBenignMalloc(); SimulateIOErrorBenign(0); } *pp = p->pNext; sqlite3_free(p->aRegion); sqlite3_free(p); }else{ pp = &p->pNext; } } } /* ** The DMS lock has not yet been taken on the shm file associated with ** pShmNode. Take the lock. Truncate the *-shm file if required. ** Return SQLITE_OK if successful, or an SQLite error code otherwise. */ static int winLockSharedMemory(winShmNode *pShmNode, DWORD nMs){ HANDLE h = pShmNode->hSharedShm; int rc = SQLITE_OK; assert( sqlite3_mutex_held(pShmNode->mutex) ); rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 1, 0); if( rc==SQLITE_OK ){ /* We have an EXCLUSIVE lock on the DMS byte. This means that this ** is the first process to open the file. Truncate it to zero bytes ** in this case. */ if( pShmNode->isReadonly ){ rc = SQLITE_READONLY_CANTINIT; }else{ rc = winHandleTruncate(h, 0); } /* Release the EXCLUSIVE lock acquired above. */ winUnlockFile(&h, WIN_SHM_DMS, 0, 1, 0); }else if( (rc & 0xFF)==SQLITE_BUSY ){ rc = SQLITE_OK; } if( rc==SQLITE_OK ){ /* Take a SHARED lock on the DMS byte. */ rc = winHandleLockTimeout(h, WIN_SHM_DMS, 1, 0, nMs); if( rc==SQLITE_OK ){ pShmNode->isUnlocked = 0; } } return rc; } /* ** Convert a UTF-8 filename into whatever form the underlying ** operating system wants filenames in. Space to hold the result ** is obtained from malloc and must be freed by the calling ** function ** ** On Cygwin, 3 possible input forms are accepted: ** - If the filename starts with "<drive>:/" or "<drive>:\", ** it is converted to UTF-16 as-is. ** - If the filename contains '/', it is assumed to be a ** Cygwin absolute path, it is converted to a win32 ** absolute path in UTF-16. ** - Otherwise it must be a filename only, the win32 filename ** is returned in UTF-16. ** Note: If the function cygwin_conv_path() fails, only ** UTF-8 -> UTF-16 conversion will be done. This can only ** happen when the file path >32k, in which case winUtf8ToUnicode() ** will fail too. */ static void *winConvertFromUtf8Filename(const char *zFilename){ void *zConverted = 0; if( osIsNT() ){ #ifdef __CYGWIN__ int nChar; LPWSTR zWideFilename; if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) && winIsDirSep(zFilename[2])) ){ int nByte; int convertflag = CCP_POSIX_TO_WIN_W; if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE; nByte = (int)osCygwin_conv_path(convertflag, zFilename, 0, 0); if( nByte>0 ){ zConverted = sqlite3MallocZero(nByte+12); if ( zConverted==0 ){ return zConverted; } zWideFilename = zConverted; /* Filenames should be prefixed, except when converted * full path already starts with "\\?\". */ if( osCygwin_conv_path(convertflag, zFilename, zWideFilename+4, nByte)==0 ){ if( (convertflag&CCP_RELATIVE) ){ memmove(zWideFilename, zWideFilename+4, nByte); }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){ memcpy(zWideFilename, L"\\\\?\\", 8); }else if( zWideFilename[6]!='?' ){ memmove(zWideFilename+6, zWideFilename+4, nByte); memcpy(zWideFilename, L"\\\\?\\UNC", 14); }else{ memmove(zWideFilename, zWideFilename+4, nByte); } return zConverted; } sqlite3_free(zConverted); } } nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); if( nChar==0 ){ return 0; } zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); if( zWideFilename==0 ){ return 0; } nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); if( nChar==0 ){ sqlite3_free(zWideFilename); zWideFilename = 0; }else if( nChar>MAX_PATH && winIsDriveLetterAndColon(zFilename) && winIsDirSep(zFilename[2]) ){ memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); zWideFilename[2] = '\\'; memcpy(zWideFilename, L"\\\\?\\", 8); }else if( nChar>MAX_PATH && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) && zFilename[2] != '?' ){ memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); memcpy(zWideFilename, L"\\\\?\\UNC", 14); } zConverted = zWideFilename; #else zConverted = winUtf8ToUnicode(zFilename); #endif /* __CYGWIN__ */ } #if defined(SQLITE_WIN32_HAS_ANSI) && defined(_WIN32) else{ zConverted = winUtf8ToMbcs(zFilename, osAreFileApisANSI()); } #endif /* caller will handle out of memory */ return zConverted; } /* ** This function is used to open a handle on a *-shm file. ** ** If SQLITE_ENABLE_SETLK_TIMEOUT is defined at build time, then the file ** is opened with FILE_FLAG_OVERLAPPED specified. If not, it is not. */ static int winHandleOpen( const char *zUtf8, /* File to open */ int *pbReadonly, /* IN/OUT: True for readonly handle */ HANDLE *ph /* OUT: New HANDLE for file */ ){ int rc = SQLITE_OK; void *zConverted = 0; int bReadonly = *pbReadonly; HANDLE h = INVALID_HANDLE_VALUE; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT const DWORD flag_overlapped = FILE_FLAG_OVERLAPPED; #else const DWORD flag_overlapped = 0; #endif /* Convert the filename to the system encoding. */ zConverted = winConvertFromUtf8Filename(zUtf8); if( zConverted==0 ){ OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8)); rc = SQLITE_IOERR_NOMEM_BKPT; goto winopenfile_out; } /* Ensure the file we are trying to open is not actually a directory. */ if( winIsDir(zConverted) ){ OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8)); rc = SQLITE_CANTOPEN_ISDIR; goto winopenfile_out; } /* TODO: platforms. ** TODO: retry-on-ioerr. */ if( osIsNT() ){ #if SQLITE_OS_WINRT CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; memset(&extendedParameters, 0, sizeof(extendedParameters)); extendedParameters.dwSize = sizeof(extendedParameters); extendedParameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; extendedParameters.dwFileFlags = flag_overlapped; extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS; h = osCreateFile2((LPCWSTR)zConverted, (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)),/* dwDesiredAccess */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ OPEN_ALWAYS, /* dwCreationDisposition */ &extendedParameters ); #else h = osCreateFileW((LPCWSTR)zConverted, /* lpFileName */ (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ NULL, /* lpSecurityAttributes */ OPEN_ALWAYS, /* dwCreationDisposition */ FILE_ATTRIBUTE_NORMAL|flag_overlapped, NULL ); #endif }else{ /* Due to pre-processor directives earlier in this file, ** SQLITE_WIN32_HAS_ANSI is always defined if osIsNT() is false. */ #ifdef SQLITE_WIN32_HAS_ANSI h = osCreateFileA((LPCSTR)zConverted, (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ NULL, /* lpSecurityAttributes */ OPEN_ALWAYS, /* dwCreationDisposition */ FILE_ATTRIBUTE_NORMAL|flag_overlapped, NULL ); #endif } if( h==INVALID_HANDLE_VALUE ){ if( bReadonly==0 ){ bReadonly = 1; rc = winHandleOpen(zUtf8, &bReadonly, &h); }else{ rc = SQLITE_CANTOPEN_BKPT; } } winopenfile_out: sqlite3_free(zConverted); *pbReadonly = bReadonly; *ph = h; return rc; } /* ** Open the shared-memory area associated with database file pDbFd. */ static int winOpenSharedMemory(winFile *pDbFd){ struct winShm *p; /* The connection to be opened */ winShmNode *pShmNode = 0; /* The underlying mmapped file */ int rc = SQLITE_OK; /* Result code */ winShmNode *pNew; /* Newly allocated winShmNode */ int nName; /* Size of zName in bytes */ assert( pDbFd->pShm==0 ); /* Not previously opened */ /* Allocate space for the new sqlite3_shm object. Also speculatively ** allocate space for a new winShmNode and filename. */ p = sqlite3MallocZero( sizeof(*p) ); if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; nName = sqlite3Strlen30(pDbFd->zPath); pNew = sqlite3MallocZero( sizeof(*pShmNode) + (i64)nName + 17 ); if( pNew==0 ){ sqlite3_free(p); return SQLITE_IOERR_NOMEM_BKPT; } pNew->zFilename = (char*)&pNew[1]; pNew->hSharedShm = INVALID_HANDLE_VALUE; pNew->isUnlocked = 1; sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); /* Open a file-handle on the *-shm file for this connection. This file-handle ** is only used for locking. The mapping of the *-shm file is created using ** the shared file handle in winShmNode.hSharedShm. */ p->bReadonly = sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0); rc = winHandleOpen(pNew->zFilename, &p->bReadonly, &p->hShm); /* Look to see if there is an existing winShmNode that can be used. ** If no matching winShmNode currently exists, then create a new one. */ winShmEnterMutex(); for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){ /* TBD need to come up with better match here. Perhaps ** use FILE_ID_BOTH_DIR_INFO Structure. */ if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; } if( pShmNode==0 ){ pShmNode = pNew; /* Allocate a mutex for this winShmNode object, if one is required. */ if( sqlite3GlobalConfig.bCoreMutex ){ pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ) rc = SQLITE_IOERR_NOMEM_BKPT; } /* Open a file-handle to use for mappings, and for the DMS lock. */ if( rc==SQLITE_OK ){ HANDLE h = INVALID_HANDLE_VALUE; pShmNode->isReadonly = p->bReadonly; rc = winHandleOpen(pNew->zFilename, &pShmNode->isReadonly, &h); pShmNode->hSharedShm = h; } /* If successful, link the new winShmNode into the global list. If an ** error occurred, free the object. */ if( rc==SQLITE_OK ){ pShmNode->pNext = winShmNodeList; winShmNodeList = pShmNode; pNew = 0; }else{ sqlite3_mutex_free(pShmNode->mutex); if( pShmNode->hSharedShm!=INVALID_HANDLE_VALUE ){ osCloseHandle(pShmNode->hSharedShm); } } } /* If no error has occurred, link the winShm object to the winShmNode and ** the winShm to pDbFd. */ if( rc==SQLITE_OK ){ p->pShmNode = pShmNode; pShmNode->nRef++; #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) p->id = pShmNode->nextShmId++; #endif pDbFd->pShm = p; }else if( p ){ winHandleClose(p->hShm); sqlite3_free(p); } assert( rc!=SQLITE_OK || pShmNode->isUnlocked==0 || pShmNode->nRegion==0 ); winShmLeaveMutex(); sqlite3_free(pNew); return rc; } /* ** Close a connection to shared-memory. Delete the underlying ** storage if deleteFlag is true. */ static int winShmUnmap( sqlite3_file *fd, /* Database holding shared memory */ int deleteFlag /* Delete after closing if true */ ){ winFile *pDbFd; /* Database holding shared-memory */ winShm *p; /* The connection to be closed */ winShmNode *pShmNode; /* The underlying shared-memory file */ pDbFd = (winFile*)fd; p = pDbFd->pShm; if( p==0 ) return SQLITE_OK; if( p->hShm!=INVALID_HANDLE_VALUE ){ osCloseHandle(p->hShm); } pShmNode = p->pShmNode; winShmEnterMutex(); /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too. */ assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ winShmPurge(pDbFd->pVfs, deleteFlag); } winShmLeaveMutex(); /* Free the connection p */ sqlite3_free(p); pDbFd->pShm = 0; return SQLITE_OK; } /* ** Change the lock state for a shared-memory segment. */ static int winShmLock( sqlite3_file *fd, /* Database file holding the shared memory */ int ofst, /* First lock to acquire or release */ int n, /* Number of locks to acquire or release */ int flags /* What to do with the lock */ ){ winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ winShm *p = pDbFd->pShm; /* The shared memory being locked */ winShmNode *pShmNode; int rc = SQLITE_OK; /* Result code */ u16 mask = (u16)((1U<<(ofst+n)) - (1U<<ofst)); /* Mask of locks to [un]take */ if( p==0 ) return SQLITE_IOERR_SHMLOCK; pShmNode = p->pShmNode; if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); assert( n>=1 ); assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE) || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); /* Check that, if this to be a blocking lock, no locks that occur later ** in the following list than the lock being obtained are already held: ** ** 1. Checkpointer lock (ofst==1). ** 2. Write lock (ofst==0). ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK). ** ** In other words, if this is a blocking lock, none of the locks that ** occur later in the above list than the lock being obtained may be ** held. ** ** It is not permitted to block on the RECOVER lock. */ #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) { u16 lockMask = (p->exclMask|p->sharedMask); assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( (ofst!=2) /* not RECOVER */ && (ofst!=1 || lockMask==0 || lockMask==2) && (ofst!=0 || lockMask<3) && (ofst<3 || lockMask<(1<<ofst)) )); } #endif /* Check if there is any work to do. There are three cases: ** ** a) An unlock operation where there are locks to unlock, ** b) An shared lock where the requested lock is not already held ** c) An exclusive lock where the requested lock is not already held ** ** The SQLite core never requests an exclusive lock that it already holds. ** This is assert()ed immediately below. */ assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK) || 0==(p->exclMask & mask) ); if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) ){ if( flags & SQLITE_SHM_UNLOCK ){ /* Case (a) - unlock. */ assert( (p->exclMask & p->sharedMask)==0 ); assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); rc = winHandleUnlock(p->hShm, ofst+WIN_SHM_BASE, n); /* If successful, also clear the bits in sharedMask/exclMask */ if( rc==SQLITE_OK ){ p->exclMask = (p->exclMask & ~mask); p->sharedMask = (p->sharedMask & ~mask); } }else{ int bExcl = ((flags & SQLITE_SHM_EXCLUSIVE) ? 1 : 0); DWORD nMs = winFileBusyTimeout(pDbFd); rc = winHandleLockTimeout(p->hShm, ofst+WIN_SHM_BASE, n, bExcl, nMs); if( rc==SQLITE_OK ){ if( bExcl ){ p->exclMask = (p->exclMask | mask); }else{ p->sharedMask = (p->sharedMask | mask); } } } } OSTRACE(( "SHM-LOCK(%d,%d,%d) pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x," " rc=%s\n", ofst, n, flags, osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, sqlite3ErrName(rc)) ); return rc; } /* ** Implement a memory barrier or memory fence on shared memory. ** ** All loads and stores begun before the barrier must complete before |
︙ | ︙ | |||
51138 51139 51140 51141 51142 51143 51144 | pShm = pDbFd->pShm; assert( pShm!=0 ); } pShmNode = pShm->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); if( pShmNode->isUnlocked ){ | > > | < < > > | < | | < | < | | | < < | < < | < < > | 51789 51790 51791 51792 51793 51794 51795 51796 51797 51798 51799 51800 51801 51802 51803 51804 51805 51806 51807 51808 51809 51810 51811 51812 51813 51814 51815 51816 51817 51818 51819 51820 51821 51822 51823 51824 51825 51826 51827 51828 51829 51830 51831 51832 51833 51834 51835 51836 51837 51838 51839 51840 51841 51842 51843 51844 51845 51846 51847 51848 51849 51850 51851 51852 51853 51854 51855 51856 51857 51858 51859 51860 51861 51862 51863 51864 51865 51866 51867 51868 | pShm = pDbFd->pShm; assert( pShm!=0 ); } pShmNode = pShm->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); if( pShmNode->isUnlocked ){ /* Take the DMS lock. */ assert( pShmNode->nRegion==0 ); rc = winLockSharedMemory(pShmNode, winFileBusyTimeout(pDbFd)); if( rc!=SQLITE_OK ) goto shmpage_out; } assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); if( pShmNode->nRegion<=iRegion ){ HANDLE hShared = pShmNode->hSharedShm; struct ShmRegion *apNew; /* New aRegion[] array */ int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ sqlite3_int64 sz; /* Current size of wal-index file */ pShmNode->szRegion = szRegion; /* The requested region is not mapped into this processes address space. ** Check to see if it has been allocated (i.e. if the wal-index file is ** large enough to contain the requested region). */ rc = winHandleSize(hShared, &sz); if( rc!=SQLITE_OK ){ rc = winLogError(rc, osGetLastError(), "winShmMap1", pDbFd->zPath); goto shmpage_out; } if( sz<nByte ){ /* The requested memory region does not exist. If isWrite is set to ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. ** ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate ** the requested memory region. */ if( !isWrite ) goto shmpage_out; rc = winHandleTruncate(hShared, nByte); if( rc!=SQLITE_OK ){ rc = winLogError(rc, osGetLastError(), "winShmMap2", pDbFd->zPath); goto shmpage_out; } } /* Map the requested memory region into this processes address space. */ apNew = (struct ShmRegion*)sqlite3_realloc64( pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) ); if( !apNew ){ rc = SQLITE_IOERR_NOMEM_BKPT; goto shmpage_out; } pShmNode->aRegion = apNew; if( pShmNode->isReadonly ){ protect = PAGE_READONLY; flags = FILE_MAP_READ; } while( pShmNode->nRegion<=iRegion ){ HANDLE hMap = NULL; /* file-mapping handle */ void *pMap = 0; /* Mapped memory region */ #if SQLITE_OS_WINRT hMap = osCreateFileMappingFromApp(hShared, NULL, protect, nByte, NULL); #elif defined(SQLITE_WIN32_HAS_WIDE) hMap = osCreateFileMappingW(hShared, NULL, protect, 0, nByte, NULL); #elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA hMap = osCreateFileMappingA(hShared, NULL, protect, 0, nByte, NULL); #endif OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", osGetCurrentProcessId(), pShmNode->nRegion, nByte, hMap ? "ok" : "failed")); if( hMap ){ int iOffset = pShmNode->nRegion*szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; #if SQLITE_OS_WINRT |
︙ | ︙ | |||
51252 51253 51254 51255 51256 51257 51258 | int iOffset = iRegion*szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; char *p = (char *)pShmNode->aRegion[iRegion].pMap; *pp = (void *)&p[iOffsetShift]; }else{ *pp = 0; } | | > > | 51897 51898 51899 51900 51901 51902 51903 51904 51905 51906 51907 51908 51909 51910 51911 51912 51913 | int iOffset = iRegion*szRegion; int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; char *p = (char *)pShmNode->aRegion[iRegion].pMap; *pp = (void *)&p[iOffsetShift]; }else{ *pp = 0; } if( pShmNode->isReadonly && rc==SQLITE_OK ){ rc = SQLITE_READONLY; } sqlite3_mutex_leave(pShmNode->mutex); return rc; } #else # define winShmMap 0 # define winShmLock 0 |
︙ | ︙ | |||
51572 51573 51574 51575 51576 51577 51578 | /**************************************************************************** **************************** sqlite3_vfs methods **************************** ** ** This division contains the implementation of methods on the ** sqlite3_vfs object. */ | | < < < < < < < < < < < < < < < < < < < < > | > > > > > > | 52219 52220 52221 52222 52223 52224 52225 52226 52227 52228 52229 52230 52231 52232 52233 52234 52235 52236 52237 52238 52239 52240 52241 52242 52243 52244 52245 52246 52247 52248 52249 52250 52251 52252 52253 52254 52255 52256 52257 52258 52259 52260 52261 52262 52263 52264 52265 52266 52267 52268 52269 52270 52271 52272 52273 | /**************************************************************************** **************************** sqlite3_vfs methods **************************** ** ** This division contains the implementation of methods on the ** sqlite3_vfs object. */ #if 0 /* No longer necessary */ /* ** Convert a filename from whatever the underlying operating system ** supports for filenames into UTF-8. Space to hold the result is ** obtained from malloc and must be freed by the calling function. */ static char *winConvertToUtf8Filename(const void *zFilename){ char *zConverted = 0; if( osIsNT() ){ zConverted = winUnicodeToUtf8(zFilename); } #ifdef SQLITE_WIN32_HAS_ANSI else{ zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI()); } #endif /* caller will handle out of memory */ return zConverted; } #endif /* ** This function returns non-zero if the specified UTF-8 string buffer ** ends with a directory separator character or one was successfully ** added to it. */ static int winMakeEndInDirSep(int nBuf, char *zBuf){ if( zBuf ){ int nLen = sqlite3Strlen30(zBuf); if( nLen>0 ){ if( winIsDirSep(zBuf[nLen-1]) ){ return 1; }else if( nLen+1<nBuf ){ if( !osGetenv ){ zBuf[nLen] = winGetDirSep(); }else if( winIsDriveLetterAndColon(zBuf) && winIsDirSep(zBuf[2]) ){ zBuf[nLen] = '\\'; zBuf[2]='\\'; }else{ zBuf[nLen] = '/'; } zBuf[nLen+1] = '\0'; return 1; } } } return 0; } |
︙ | ︙ | |||
51652 51653 51654 51655 51656 51657 51658 | } /* ** Create a temporary file name and store the resulting pointer into pzBuf. ** The pointer returned in pzBuf must be freed via sqlite3_free(). */ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ | | | 52286 52287 52288 52289 52290 52291 52292 52293 52294 52295 52296 52297 52298 52299 52300 | } /* ** Create a temporary file name and store the resulting pointer into pzBuf. ** The pointer returned in pzBuf must be freed via sqlite3_free(). */ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ static const char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; size_t i, j; DWORD pid; int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); i64 nMax, nBuf, nDir, nLen; |
︙ | ︙ | |||
51703 51704 51705 51706 51707 51708 51709 | } sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); } sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); } #if defined(__CYGWIN__) | | | | | | | < > > | | | 52337 52338 52339 52340 52341 52342 52343 52344 52345 52346 52347 52348 52349 52350 52351 52352 52353 52354 52355 52356 52357 52358 52359 52360 52361 52362 52363 52364 52365 52366 52367 52368 52369 52370 52371 52372 52373 52374 52375 52376 52377 52378 52379 52380 52381 52382 52383 52384 52385 52386 52387 52388 52389 52390 52391 52392 52393 52394 52395 52396 52397 52398 52399 52400 52401 52402 | } sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); } sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_TEMPDIR)); } #if defined(__CYGWIN__) else if( osGetenv!=NULL ){ static const char *azDirs[] = { 0, /* getenv("SQLITE_TMPDIR") */ 0, /* getenv("TMPDIR") */ 0, /* getenv("TMP") */ 0, /* getenv("TEMP") */ 0, /* getenv("USERPROFILE") */ "/var/tmp", "/usr/tmp", "/tmp", ".", 0 /* List terminator */ }; unsigned int i; const char *zDir = 0; if( !azDirs[0] ) azDirs[0] = osGetenv("SQLITE_TMPDIR"); if( !azDirs[1] ) azDirs[1] = osGetenv("TMPDIR"); if( !azDirs[2] ) azDirs[2] = osGetenv("TMP"); if( !azDirs[3] ) azDirs[3] = osGetenv("TEMP"); if( !azDirs[4] ) azDirs[4] = osGetenv("USERPROFILE"); for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ void *zConverted; if( zDir==0 ) continue; /* If the path starts with a drive letter followed by the colon ** character, assume it is already a native Win32 path; otherwise, ** it must be converted to a native Win32 path via the Cygwin API ** prior to using it. */ { zConverted = winConvertFromUtf8Filename(zDir); if( !zConverted ){ sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } if( winIsDir(zConverted) ){ sqlite3_snprintf(nMax, zBuf, "%s", zDir); sqlite3_free(zConverted); break; } sqlite3_free(zConverted); #if 0 /* No longer necessary */ }else{ zConverted = sqlite3MallocZero( nMax+1 ); if( !zConverted ){ sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } if( osCygwin_conv_path( CCP_POSIX_TO_WIN_W, zDir, zConverted, nMax+1)<0 ){ sqlite3_free(zConverted); sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, "winGetTempname2", zDir); } |
︙ | ︙ | |||
51779 51780 51781 51782 51783 51784 51785 51786 51787 51788 | } sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); sqlite3_free(zUtf8); sqlite3_free(zConverted); break; } sqlite3_free(zConverted); } } } | > > > | | 52414 52415 52416 52417 52418 52419 52420 52421 52422 52423 52424 52425 52426 52427 52428 52429 52430 52431 52432 52433 52434 | } sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); sqlite3_free(zUtf8); sqlite3_free(zConverted); break; } sqlite3_free(zConverted); #endif /* No longer necessary */ } } } #endif #if !SQLITE_OS_WINRT && defined(_WIN32) else if( osIsNT() ){ char *zMulti; LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) ); if( !zWidePath ){ sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; |
︙ | ︙ | |||
51906 51907 51908 51909 51910 51911 51912 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, GetFileExInfoStandard, &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} if( !rc ){ return 0; /* Invalid name? */ } attr = sAttrData.dwFileAttributes; | | > > > > > > | 52544 52545 52546 52547 52548 52549 52550 52551 52552 52553 52554 52555 52556 52557 52558 52559 52560 52561 52562 52563 52564 52565 52566 52567 52568 52569 52570 52571 52572 52573 52574 52575 52576 52577 52578 52579 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, GetFileExInfoStandard, &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} if( !rc ){ return 0; /* Invalid name? */ } attr = sAttrData.dwFileAttributes; #if SQLITE_OS_WINCE==0 && defined(SQLITE_WIN32_HAS_ANSI) }else{ attr = osGetFileAttributesA((char*)zConverted); #endif } return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY); } /* forward reference */ static int winAccess( sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ ); /* ** The Windows version of xAccess() accepts an extra bit in the flags ** parameter that prevents an anti-virus retry loop. */ #define NORETRY 0x4000 /* ** Open a file. */ static int winOpen( sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ const char *zName, /* Name of the file (UTF-8) */ sqlite3_file *id, /* Write the SQLite file handle here */ |
︙ | ︙ | |||
51946 51947 51948 51949 51950 51951 51952 51953 51954 51955 51956 51957 51958 51959 | int isTemp = 0; #endif winVfsAppData *pAppData; winFile *pFile = (winFile*)id; void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ char *zTmpname = 0; /* For temporary filename, if necessary. */ int rc = SQLITE_OK; /* Function Return Code */ | > | 52590 52591 52592 52593 52594 52595 52596 52597 52598 52599 52600 52601 52602 52603 52604 | int isTemp = 0; #endif winVfsAppData *pAppData; winFile *pFile = (winFile*)id; void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; int isRO = 0; /* file is known to be accessible readonly */ /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ char *zTmpname = 0; /* For temporary filename, if necessary. */ int rc = SQLITE_OK; /* Function Return Code */ |
︙ | ︙ | |||
52110 52111 52112 52113 52114 52115 52116 | h = osCreateFile2((LPCWSTR)zConverted, dwDesiredAccess, dwShareMode, dwCreationDisposition, &extendedParameters); if( h!=INVALID_HANDLE_VALUE ) break; if( isReadWrite ){ | | | | | | | | | 52755 52756 52757 52758 52759 52760 52761 52762 52763 52764 52765 52766 52767 52768 52769 52770 52771 52772 52773 52774 52775 52776 52777 52778 52779 52780 52781 52782 52783 52784 52785 52786 52787 52788 52789 52790 52791 52792 52793 52794 52795 52796 52797 52798 52799 52800 52801 52802 52803 52804 52805 52806 52807 52808 52809 52810 52811 52812 52813 52814 52815 52816 52817 52818 52819 52820 52821 52822 52823 | h = osCreateFile2((LPCWSTR)zConverted, dwDesiredAccess, dwShareMode, dwCreationDisposition, &extendedParameters); if( h!=INVALID_HANDLE_VALUE ) break; if( isReadWrite ){ int rc2; sqlite3BeginBenignMalloc(); rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } }while( winRetryIoerr(&cnt, &lastErrno) ); #else do{ h = osCreateFileW((LPCWSTR)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); if( h!=INVALID_HANDLE_VALUE ) break; if( isReadWrite ){ int rc2; sqlite3BeginBenignMalloc(); rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } }while( winRetryIoerr(&cnt, &lastErrno) ); #endif } #ifdef SQLITE_WIN32_HAS_ANSI else{ do{ h = osCreateFileA((LPCSTR)zConverted, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL); if( h!=INVALID_HANDLE_VALUE ) break; if( isReadWrite ){ int rc2; sqlite3BeginBenignMalloc(); rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ|NORETRY, &isRO); sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } }while( winRetryIoerr(&cnt, &lastErrno) ); } #endif winLogIoerr(cnt, __LINE__); OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); if( h==INVALID_HANDLE_VALUE ){ sqlite3_free(zConverted); sqlite3_free(zTmpname); if( isReadWrite && isRO && !isExclusive ){ return winOpen(pVfs, zName, id, ((flags|SQLITE_OPEN_READONLY) & ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); }else{ pFile->lastErrno = lastErrno; winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
︙ | ︙ | |||
52366 52367 52368 52369 52370 52371 52372 52373 52374 52375 52376 52377 52378 52379 52380 | int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ ){ DWORD attr; int rc = 0; DWORD lastErrno = 0; void *zConverted; UNUSED_PARAMETER(pVfs); SimulateIOError( return SQLITE_IOERR_ACCESS; ); OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", zFilename, flags, pResOut)); if( zFilename==0 ){ *pResOut = 0; | > > > > > > | 53011 53012 53013 53014 53015 53016 53017 53018 53019 53020 53021 53022 53023 53024 53025 53026 53027 53028 53029 53030 53031 | int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ ){ DWORD attr; int rc = 0; DWORD lastErrno = 0; void *zConverted; int noRetry = 0; /* Do not use winRetryIoerr() */ UNUSED_PARAMETER(pVfs); if( (flags & NORETRY)!=0 ){ noRetry = 1; flags &= ~NORETRY; } SimulateIOError( return SQLITE_IOERR_ACCESS; ); OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", zFilename, flags, pResOut)); if( zFilename==0 ){ *pResOut = 0; |
︙ | ︙ | |||
52390 52391 52392 52393 52394 52395 52396 | } if( osIsNT() ){ int cnt = 0; WIN32_FILE_ATTRIBUTE_DATA sAttrData; memset(&sAttrData, 0, sizeof(sAttrData)); while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, GetFileExInfoStandard, | > > | > | 53041 53042 53043 53044 53045 53046 53047 53048 53049 53050 53051 53052 53053 53054 53055 53056 53057 53058 | } if( osIsNT() ){ int cnt = 0; WIN32_FILE_ATTRIBUTE_DATA sAttrData; memset(&sAttrData, 0, sizeof(sAttrData)); while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, GetFileExInfoStandard, &sAttrData)) && !noRetry && winRetryIoerr(&cnt, &lastErrno) ){ /* Loop until true */} if( rc ){ /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file ** as if it does not exist. */ if( flags==SQLITE_ACCESS_EXISTS && sAttrData.nFileSizeHigh==0 && sAttrData.nFileSizeLow==0 ){ |
︙ | ︙ | |||
52458 52459 52460 52461 52462 52463 52464 52465 52466 52467 52468 52469 52470 52471 | */ static BOOL winIsDriveLetterAndColon( const char *zPathname ){ return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); } /* ** Returns non-zero if the specified path name should be used verbatim. If ** non-zero is returned from this function, the calling function must simply ** use the provided path name verbatim -OR- resolve it into a full path name ** using the GetFullPathName Win32 API function (if available). */ static BOOL winIsVerbatimPathname( | > | 53112 53113 53114 53115 53116 53117 53118 53119 53120 53121 53122 53123 53124 53125 53126 | */ static BOOL winIsDriveLetterAndColon( const char *zPathname ){ return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); } #ifdef _WIN32 /* ** Returns non-zero if the specified path name should be used verbatim. If ** non-zero is returned from this function, the calling function must simply ** use the provided path name verbatim -OR- resolve it into a full path name ** using the GetFullPathName Win32 API function (if available). */ static BOOL winIsVerbatimPathname( |
︙ | ︙ | |||
52494 52495 52496 52497 52498 52499 52500 52501 52502 52503 52504 52505 52506 52507 52508 52509 52510 52511 52512 | /* ** If we get to this point, the path name should almost certainly be a purely ** relative one (i.e. not a UNC name, not absolute, and not volume relative). */ return FALSE; } /* ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ static int winFullPathnameNoMutex( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | | | | | | | | | | | | < | | > > > | | | 53149 53150 53151 53152 53153 53154 53155 53156 53157 53158 53159 53160 53161 53162 53163 53164 53165 53166 53167 53168 53169 53170 53171 53172 53173 53174 53175 53176 53177 53178 53179 53180 53181 53182 53183 53184 53185 53186 53187 53188 53189 53190 53191 53192 53193 53194 53195 53196 53197 53198 53199 53200 53201 53202 53203 53204 53205 53206 53207 53208 53209 53210 53211 53212 53213 53214 53215 53216 53217 53218 53219 53220 53221 53222 53223 53224 53225 53226 53227 53228 53229 53230 53231 53232 53233 53234 53235 53236 53237 53238 53239 53240 53241 53242 53243 53244 53245 53246 53247 53248 53249 53250 53251 53252 53253 53254 53255 53256 53257 53258 53259 53260 53261 53262 53263 53264 53265 53266 53267 53268 53269 53270 53271 53272 53273 53274 53275 53276 53277 53278 53279 53280 53281 53282 53283 53284 53285 53286 53287 53288 53289 53290 53291 53292 53293 53294 53295 53296 53297 53298 53299 53300 53301 53302 53303 53304 53305 53306 53307 53308 53309 53310 53311 53312 53313 53314 53315 53316 53317 53318 53319 53320 53321 53322 53323 53324 53325 53326 53327 53328 53329 53330 53331 53332 53333 53334 53335 53336 53337 53338 53339 53340 53341 53342 53343 53344 53345 53346 53347 53348 53349 53350 53351 53352 53353 53354 53355 53356 53357 53358 53359 53360 53361 53362 53363 53364 53365 53366 53367 53368 53369 53370 53371 53372 53373 53374 53375 53376 53377 53378 53379 53380 53381 53382 53383 53384 53385 53386 53387 53388 53389 53390 53391 53392 53393 53394 53395 53396 53397 53398 53399 53400 53401 53402 53403 53404 53405 53406 53407 53408 53409 53410 53411 53412 53413 | /* ** If we get to this point, the path name should almost certainly be a purely ** relative one (i.e. not a UNC name, not absolute, and not volume relative). */ return FALSE; } #endif /* _WIN32 */ #ifdef __CYGWIN__ /* ** Simplify a filename into its canonical form ** by making the following changes: ** ** * convert any '/' to '\' (win32) or reverse (Cygwin) ** * removing any trailing and duplicate / (except for UNC paths) ** * convert /./ into just / ** ** Changes are made in-place. Return the new name length. ** ** The original filename is in z[0..]. If the path is shortened, ** no-longer used bytes will be written by '\0'. */ static void winSimplifyName(char *z){ int i, j; for(i=j=0; z[i]; ++i){ if( winIsDirSep(z[i]) ){ #if !defined(SQLITE_TEST) /* Some test-cases assume that "./foo" and "foo" are different */ if( z[i+1]=='.' && winIsDirSep(z[i+2]) ){ ++i; continue; } #endif if( !z[i+1] || (winIsDirSep(z[i+1]) && (i!=0)) ){ continue; } z[j++] = osGetenv?'/':'\\'; }else{ z[j++] = z[i]; } } while(j<i) z[j++] = '\0'; } #define SQLITE_MAX_SYMLINKS 100 static int mkFullPathname( const char *zPath, /* Input path */ char *zOut, /* Output buffer */ int nOut /* Allocated size of buffer zOut */ ){ int nPath = sqlite3Strlen30(zPath); int iOff = 0; if( zPath[0]!='/' ){ if( osGetcwd(zOut, nOut-2)==0 ){ return winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "getcwd", zPath); } iOff = sqlite3Strlen30(zOut); zOut[iOff++] = '/'; } if( (iOff+nPath+1)>nOut ){ /* SQLite assumes that xFullPathname() nul-terminates the output buffer ** even if it returns an error. */ zOut[iOff] = '\0'; return SQLITE_CANTOPEN_BKPT; } sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); return SQLITE_OK; } #endif /* __CYGWIN__ */ /* ** Turn a relative pathname into a full pathname. Write the full ** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname ** bytes in size. */ static int winFullPathnameNoMutex( sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ ){ #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT int nByte; void *zConverted; char *zOut; #endif /* If this path name begins with "/X:" or "\\?\", where "X" is any ** alphabetic character, discard the initial "/" from the pathname. */ if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1) || winIsLongPathPrefix(zRelative+1)) ){ zRelative++; } SimulateIOError( return SQLITE_ERROR ); #ifdef __CYGWIN__ if( osGetcwd ){ zFull[nFull-1] = '\0'; if( !winIsDriveLetterAndColon(zRelative) || !winIsDirSep(zRelative[2]) ){ int rc = SQLITE_OK; int nLink = 1; /* Number of symbolic links followed so far */ const char *zIn = zRelative; /* Input path for each iteration of loop */ char *zDel = 0; struct stat buf; UNUSED_PARAMETER(pVfs); do { /* Call lstat() on path zIn. Set bLink to true if the path is a symbolic ** link, or false otherwise. */ int bLink = 0; if( osLstat && osReadlink ) { if( osLstat(zIn, &buf)!=0 ){ int myErrno = osErrno; if( myErrno!=ENOENT ){ rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)myErrno, "lstat", zIn); } }else{ bLink = ((buf.st_mode & 0170000) == 0120000); } if( bLink ){ if( zDel==0 ){ zDel = sqlite3MallocZero(nFull); if( zDel==0 ) rc = SQLITE_NOMEM; }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ rc = SQLITE_CANTOPEN_BKPT; } if( rc==SQLITE_OK ){ nByte = osReadlink(zIn, zDel, nFull-1); if( nByte ==(DWORD)-1 ){ rc = winLogError(SQLITE_CANTOPEN_BKPT, (DWORD)osErrno, "readlink", zIn); }else{ if( zDel[0]!='/' ){ int n; for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); if( nByte+n+1>nFull ){ rc = SQLITE_CANTOPEN_BKPT; }else{ memmove(&zDel[n], zDel, nByte+1); memcpy(zDel, zIn, n); nByte += n; } } zDel[nByte] = '\0'; } } zIn = zDel; } } assert( rc!=SQLITE_OK || zIn!=zFull || zIn[0]=='/' ); if( rc==SQLITE_OK && zIn!=zFull ){ rc = mkFullPathname(zIn, zFull, nFull); } if( bLink==0 ) break; zIn = zFull; }while( rc==SQLITE_OK ); sqlite3_free(zDel); winSimplifyName(zFull); return rc; } } #endif /* __CYGWIN__ */ #if 0 /* This doesn't work correctly at all! See: <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> */ SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); assert( nFull>=pVfs->mxPathname ); char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); if( !zOut ){ return SQLITE_IOERR_NOMEM_BKPT; } if( osCygwin_conv_path( CCP_POSIX_TO_WIN_W, zRelative, zOut, pVfs->mxPathname+1)<0 ){ sqlite3_free(zOut); return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, "winFullPathname2", zRelative); }else{ char *zUtf8 = winConvertToUtf8Filename(zOut); if( !zUtf8 ){ sqlite3_free(zOut); return SQLITE_IOERR_NOMEM_BKPT; } sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); sqlite3_free(zUtf8); sqlite3_free(zOut); } return SQLITE_OK; #endif #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32) SimulateIOError( return SQLITE_ERROR ); /* WinCE has no concept of a relative pathname, or so I am told. */ /* WinRT has no way to convert a relative path to an absolute one. */ if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a backslash. */ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", sqlite3_data_directory, winGetDirSep(), zRelative); }else{ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); } return SQLITE_OK; #endif #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT #if defined(_WIN32) /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this ** function failing. This function could fail if, for example, the ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a backslash. */ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", sqlite3_data_directory, winGetDirSep(), zRelative); return SQLITE_OK; } #endif zConverted = winConvertFromUtf8Filename(zRelative); if( zConverted==0 ){ return SQLITE_IOERR_NOMEM_BKPT; } if( osIsNT() ){ LPWSTR zTemp; nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); if( nByte==0 ){ sqlite3_free(zConverted); return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname1", zRelative); } nByte += 3; zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ sqlite3_free(zConverted); return SQLITE_IOERR_NOMEM_BKPT; } nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); if( nByte==0 ){ sqlite3_free(zConverted); sqlite3_free(zTemp); return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname2", zRelative); } sqlite3_free(zConverted); |
︙ | ︙ | |||
52669 52670 52671 52672 52673 52674 52675 | } sqlite3_free(zConverted); zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); sqlite3_free(zTemp); } #endif if( zOut ){ | > > | > > > > > > > > > > > > > > > > > | 53437 53438 53439 53440 53441 53442 53443 53444 53445 53446 53447 53448 53449 53450 53451 53452 53453 53454 53455 53456 53457 53458 53459 53460 53461 53462 53463 53464 53465 53466 53467 53468 53469 53470 | } sqlite3_free(zConverted); zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); sqlite3_free(zTemp); } #endif if( zOut ){ #ifdef __CYGWIN__ if( memcmp(zOut, "\\\\?\\", 4) ){ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); }else if( memcmp(zOut+4, "UNC\\", 4) ){ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+4); }else{ char *p = zOut+6; *p = '\\'; if( osGetcwd ){ /* On Cygwin, UNC paths use forward slashes */ while( *p ){ if( *p=='\\' ) *p = '/'; ++p; } } sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut+6); } #else sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); #endif /* __CYGWIN__ */ sqlite3_free(zOut); return SQLITE_OK; }else{ return SQLITE_IOERR_NOMEM_BKPT; } #endif } |
︙ | ︙ | |||
52699 52700 52701 52702 52703 52704 52705 | #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ HANDLE h; | | > > | 53486 53487 53488 53489 53490 53491 53492 53493 53494 53495 53496 53497 53498 53499 53500 53501 53502 | #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ HANDLE h; #if 0 /* This doesn't work correctly at all! See: <https://marc.info/?l=sqlite-users&m=139299149416314&w=2> */ int nFull = pVfs->mxPathname+1; char *zFull = sqlite3MallocZero( nFull ); void *zConverted = 0; if( zFull==0 ){ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); return 0; } |
︙ | ︙ | |||
53066 53067 53068 53069 53070 53071 53072 | winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; #endif /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ | | | 53855 53856 53857 53858 53859 53860 53861 53862 53863 53864 53865 53866 53867 53868 53869 | winGetSystemCall, /* xGetSystemCall */ winNextSystemCall, /* xNextSystemCall */ }; #endif /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ assert( ArraySize(aSyscall)==89 ); /* get memory map allocation granularity */ memset(&winSysInfo, 0, sizeof(SYSTEM_INFO)); #if SQLITE_OS_WINRT osGetNativeSystemInfo(&winSysInfo); #else osGetSystemInfo(&winSysInfo); |
︙ | ︙ | |||
54124 54125 54126 54127 54128 54129 54130 | #define BITVEC_MXHASH (BITVEC_NINT/2) /* Hashing function for the aHash representation. ** Empirical testing showed that the *37 multiplier ** (an arbitrary prime)in the hash function provided ** no fewer collisions than the no-op *1. */ #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) | | | 54913 54914 54915 54916 54917 54918 54919 54920 54921 54922 54923 54924 54925 54926 54927 | #define BITVEC_MXHASH (BITVEC_NINT/2) /* Hashing function for the aHash representation. ** Empirical testing showed that the *37 multiplier ** (an arbitrary prime)in the hash function provided ** no fewer collisions than the no-op *1. */ #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) #define BITVEC_NPTR ((u32)(BITVEC_USIZE/sizeof(Bitvec *))) /* ** A bitmap is an instance of the following structure. ** ** This bitmap records the existence of zero or more bits ** with values between 1 and iSize, inclusive. |
︙ | ︙ | |||
54307 54308 54309 54310 54311 54312 54313 | i = i%p->iDivisor; p = p->u.apSub[bin]; if (!p) { return; } } if( p->iSize<=BITVEC_NBIT ){ | | | 55096 55097 55098 55099 55100 55101 55102 55103 55104 55105 55106 55107 55108 55109 55110 | i = i%p->iDivisor; p = p->u.apSub[bin]; if (!p) { return; } } if( p->iSize<=BITVEC_NBIT ){ p->u.aBitmap[i/BITVEC_SZELEM] &= ~(BITVEC_TELEM)(1<<(i&(BITVEC_SZELEM-1))); }else{ unsigned int j; u32 *aiValues = pBuf; memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); memset(p->u.aHash, 0, sizeof(p->u.aHash)); p->nSet = 0; for(j=0; j<BITVEC_NINT; j++){ |
︙ | ︙ | |||
54358 54359 54360 54361 54362 54363 54364 | /* ** Let V[] be an array of unsigned characters sufficient to hold ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. ** Then the following macros can be used to set, clear, or test ** individual bits within V. */ #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) | | | 55147 55148 55149 55150 55151 55152 55153 55154 55155 55156 55157 55158 55159 55160 55161 | /* ** Let V[] be an array of unsigned characters sufficient to hold ** up to N bits. Let I be an integer between 0 and N. 0<=I<N. ** Then the following macros can be used to set, clear, or test ** individual bits within V. */ #define SETBIT(V,I) V[I>>3] |= (1<<(I&7)) #define CLEARBIT(V,I) V[I>>3] &= ~(BITVEC_TELEM)(1<<(I&7)) #define TESTBIT(V,I) (V[I>>3]&(1<<(I&7)))!=0 /* ** This routine runs an extensive test of the Bitvec code. ** ** The input is an array of integers that acts as a program ** to test the Bitvec. The integers are opcodes followed |
︙ | ︙ | |||
55642 55643 55644 55645 55646 55647 55648 | int nSlot; /* The number of pcache slots */ int nReserve; /* Try to keep nFreeSlot above this */ void *pStart, *pEnd; /* Bounds of global page cache memory */ /* Above requires no mutex. Use mutex below for variable that follow. */ sqlite3_mutex *mutex; /* Mutex for accessing the following: */ PgFreeslot *pFree; /* Free page blocks */ int nFreeSlot; /* Number of unused pcache slots */ | < < < < | 56431 56432 56433 56434 56435 56436 56437 56438 56439 56440 56441 56442 56443 56444 | int nSlot; /* The number of pcache slots */ int nReserve; /* Try to keep nFreeSlot above this */ void *pStart, *pEnd; /* Bounds of global page cache memory */ /* Above requires no mutex. Use mutex below for variable that follow. */ sqlite3_mutex *mutex; /* Mutex for accessing the following: */ PgFreeslot *pFree; /* Free page blocks */ int nFreeSlot; /* Number of unused pcache slots */ int bUnderPressure; /* True if low on PAGECACHE memory */ } pcache1_g; /* ** All code in this file should access the global structure above via the ** alias "pcache1". This ensures that the WSD emulation is used when ** compiling for systems that do not support real WSD. |
︙ | ︙ | |||
55693 55694 55695 55696 55697 55698 55699 | if( n==0 ) sz = 0; sz = ROUNDDOWN8(sz); pcache1.szSlot = sz; pcache1.nSlot = pcache1.nFreeSlot = n; pcache1.nReserve = n>90 ? 10 : (n/10 + 1); pcache1.pStart = pBuf; pcache1.pFree = 0; | | | 56478 56479 56480 56481 56482 56483 56484 56485 56486 56487 56488 56489 56490 56491 56492 | if( n==0 ) sz = 0; sz = ROUNDDOWN8(sz); pcache1.szSlot = sz; pcache1.nSlot = pcache1.nFreeSlot = n; pcache1.nReserve = n>90 ? 10 : (n/10 + 1); pcache1.pStart = pBuf; pcache1.pFree = 0; AtomicStore(&pcache1.bUnderPressure,0); while( n-- ){ p = (PgFreeslot*)pBuf; p->pNext = pcache1.pFree; pcache1.pFree = p; pBuf = (void*)&((char*)pBuf)[sz]; } pcache1.pEnd = pBuf; |
︙ | ︙ | |||
55761 55762 55763 55764 55765 55766 55767 | assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); if( nByte<=pcache1.szSlot ){ sqlite3_mutex_enter(pcache1.mutex); p = (PgHdr1 *)pcache1.pFree; if( p ){ pcache1.pFree = pcache1.pFree->pNext; pcache1.nFreeSlot--; | | | 56546 56547 56548 56549 56550 56551 56552 56553 56554 56555 56556 56557 56558 56559 56560 | assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); if( nByte<=pcache1.szSlot ){ sqlite3_mutex_enter(pcache1.mutex); p = (PgHdr1 *)pcache1.pFree; if( p ){ pcache1.pFree = pcache1.pFree->pNext; pcache1.nFreeSlot--; AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot<pcache1.nReserve); assert( pcache1.nFreeSlot>=0 ); sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); } sqlite3_mutex_leave(pcache1.mutex); } if( p==0 ){ |
︙ | ︙ | |||
55800 55801 55802 55803 55804 55805 55806 | PgFreeslot *pSlot; sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); pSlot = (PgFreeslot*)p; pSlot->pNext = pcache1.pFree; pcache1.pFree = pSlot; pcache1.nFreeSlot++; | | | 56585 56586 56587 56588 56589 56590 56591 56592 56593 56594 56595 56596 56597 56598 56599 | PgFreeslot *pSlot; sqlite3_mutex_enter(pcache1.mutex); sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); pSlot = (PgFreeslot*)p; pSlot->pNext = pcache1.pFree; pcache1.pFree = pSlot; pcache1.nFreeSlot++; AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot<pcache1.nReserve); assert( pcache1.nFreeSlot<=pcache1.nSlot ); sqlite3_mutex_leave(pcache1.mutex); }else{ assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) ); sqlite3MemdebugSetType(p, MEMTYPE_HEAP); #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS { |
︙ | ︙ | |||
55931 55932 55933 55934 55935 55936 55937 | ** Or, the heap is used for all page cache memory but the heap is ** under memory pressure, then again it is desirable to avoid ** allocating a new page cache entry in order to avoid stressing ** the heap even further. */ static int pcache1UnderMemoryPressure(PCache1 *pCache){ if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ | | | 56716 56717 56718 56719 56720 56721 56722 56723 56724 56725 56726 56727 56728 56729 56730 | ** Or, the heap is used for all page cache memory but the heap is ** under memory pressure, then again it is desirable to avoid ** allocating a new page cache entry in order to avoid stressing ** the heap even further. */ static int pcache1UnderMemoryPressure(PCache1 *pCache){ if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ return AtomicLoad(&pcache1.bUnderPressure); }else{ return sqlite3HeapNearlyFull(); } } /******************************************************************************/ /******** General Implementation Functions ************************************/ |
︙ | ︙ | |||
59210 59211 59212 59213 59214 59215 59216 59217 59218 59219 59220 59221 59222 59223 | sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; releaseAllSavepoints(pPager); if( pagerUseWal(pPager) ){ assert( !isOpen(pPager->jfd) ); sqlite3WalEndReadTransaction(pPager->pWal); pPager->eState = PAGER_OPEN; }else if( !pPager->exclusiveMode ){ int rc; /* Error code returned by pagerUnlockDb() */ int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; /* If the operating system support deletion of open files, then | > > > > > > > > > | 59995 59996 59997 59998 59999 60000 60001 60002 60003 60004 60005 60006 60007 60008 60009 60010 60011 60012 60013 60014 60015 60016 60017 | sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; releaseAllSavepoints(pPager); if( pagerUseWal(pPager) ){ assert( !isOpen(pPager->jfd) ); if( pPager->eState==PAGER_ERROR ){ /* If an IO error occurs in wal.c while attempting to wrap the wal file, ** then the Wal object may be holding a write-lock but no read-lock. ** This call ensures that the write-lock is dropped as well. We cannot ** have sqlite3WalEndReadTransaction() drop the write-lock, as it once ** did, because this would break "BEGIN EXCLUSIVE" handling for ** SQLITE_ENABLE_SETLK_TIMEOUT builds. */ sqlite3WalEndWriteTransaction(pPager->pWal); } sqlite3WalEndReadTransaction(pPager->pWal); pPager->eState = PAGER_OPEN; }else if( !pPager->exclusiveMode ){ int rc; /* Error code returned by pagerUnlockDb() */ int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; /* If the operating system support deletion of open files, then |
︙ | ︙ | |||
65668 65669 65670 65671 65672 65673 65674 65675 65676 65677 65678 65679 65680 65681 | #define walFrameOffset(iFrame, szPage) ( \ WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ ) /* ** An open write-ahead log file is represented by an instance of the ** following object. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ sqlite3_file *pDbFd; /* File handle for the database file */ sqlite3_file *pWalFd; /* File handle for WAL file */ u32 iCallback; /* Value to pass to log callback (or 0) */ i64 mxWalSize; /* Truncate WAL to this size upon reset */ | > > > > > | 66462 66463 66464 66465 66466 66467 66468 66469 66470 66471 66472 66473 66474 66475 66476 66477 66478 66479 66480 | #define walFrameOffset(iFrame, szPage) ( \ WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ ) /* ** An open write-ahead log file is represented by an instance of the ** following object. ** ** writeLock: ** This is usually set to 1 whenever the WRITER lock is held. However, ** if it is set to 2, then the WRITER lock is held but must be released ** by walHandleException() if a SEH exception is thrown. */ struct Wal { sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ sqlite3_file *pDbFd; /* File handle for the database file */ sqlite3_file *pWalFd; /* File handle for WAL file */ u32 iCallback; /* Value to pass to log callback (or 0) */ i64 mxWalSize; /* Truncate WAL to this size upon reset */ |
︙ | ︙ | |||
65758 65759 65760 65761 65762 65763 65764 | int nSegment; /* Number of entries in aSegment[] */ struct WalSegment { int iNext; /* Next slot in aIndex[] not yet returned */ ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ u32 *aPgno; /* Array of page numbers. */ int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ int iZero; /* Frame number associated with aPgno[0] */ | | > > > > | 66557 66558 66559 66560 66561 66562 66563 66564 66565 66566 66567 66568 66569 66570 66571 66572 66573 66574 66575 66576 | int nSegment; /* Number of entries in aSegment[] */ struct WalSegment { int iNext; /* Next slot in aIndex[] not yet returned */ ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ u32 *aPgno; /* Array of page numbers. */ int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ int iZero; /* Frame number associated with aPgno[0] */ } aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */ }; /* Size (in bytes) of a WalIterator object suitable for N or fewer segments */ #define SZ_WALITERATOR(N) \ (offsetof(WalIterator,aSegment)*(N)*sizeof(struct WalSegment)) /* ** Define the parameters of the hash tables in the wal-index file. There ** is a hash-table following every HASHTABLE_NPAGE page numbers in the ** wal-index. ** ** Changing any of these constants will alter the wal-index format and |
︙ | ︙ | |||
66028 66029 66030 66031 66032 66033 66034 | if( aIn ){ s1 = aIn[0]; s2 = aIn[1]; }else{ s1 = s2 = 0; } | > | < < < | 66831 66832 66833 66834 66835 66836 66837 66838 66839 66840 66841 66842 66843 66844 66845 66846 | if( aIn ){ s1 = aIn[0]; s2 = aIn[1]; }else{ s1 = s2 = 0; } /* nByte is a multiple of 8 between 8 and 65536 */ assert( nByte>=8 && (nByte&7)==0 && nByte<=65536 ); if( !nativeCksum ){ do { s1 += BYTESWAP32(aData[0]) + s2; s2 += BYTESWAP32(aData[1]) + s1; aData += 2; }while( aData<aEnd ); |
︙ | ︙ | |||
67121 67122 67123 67124 67125 67126 67127 | ** it only runs if there is actually content in the log (mxFrame>0). */ assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); iLast = pWal->hdr.mxFrame; /* Allocate space for the WalIterator object. */ nSegment = walFramePage(iLast) + 1; | | < | 67922 67923 67924 67925 67926 67927 67928 67929 67930 67931 67932 67933 67934 67935 67936 | ** it only runs if there is actually content in the log (mxFrame>0). */ assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); iLast = pWal->hdr.mxFrame; /* Allocate space for the WalIterator object. */ nSegment = walFramePage(iLast) + 1; nByte = SZ_WALITERATOR(nSegment) + iLast*sizeof(ht_slot); p = (WalIterator *)sqlite3_malloc64(nByte + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) ); if( !p ){ return SQLITE_NOMEM_BKPT; } |
︙ | ︙ | |||
67193 67194 67195 67196 67197 67198 67199 | ** they are supported by the VFS, and (b) the database handle is configured ** with a busy-timeout. Return 1 if blocking locks are successfully enabled, ** or 0 otherwise. */ static int walEnableBlocking(Wal *pWal){ int res = 0; if( pWal->db ){ | | | 67993 67994 67995 67996 67997 67998 67999 68000 68001 68002 68003 68004 68005 68006 68007 | ** they are supported by the VFS, and (b) the database handle is configured ** with a busy-timeout. Return 1 if blocking locks are successfully enabled, ** or 0 otherwise. */ static int walEnableBlocking(Wal *pWal){ int res = 0; if( pWal->db ){ int tmout = pWal->db->setlkTimeout; if( tmout ){ res = walEnableBlockingMs(pWal, tmout); } } return res; } |
︙ | ︙ | |||
67579 67580 67581 67582 67583 67584 67585 | ** 4) Returns SQLITE_IOERR. */ static int walHandleException(Wal *pWal){ if( pWal->exclusiveMode==0 ){ static const int S = 1; static const int E = (1<<SQLITE_SHM_NLOCK); int ii; | > > | | 68379 68380 68381 68382 68383 68384 68385 68386 68387 68388 68389 68390 68391 68392 68393 68394 68395 | ** 4) Returns SQLITE_IOERR. */ static int walHandleException(Wal *pWal){ if( pWal->exclusiveMode==0 ){ static const int S = 1; static const int E = (1<<SQLITE_SHM_NLOCK); int ii; u32 mUnlock; if( pWal->writeLock==2 ) pWal->writeLock = 0; mUnlock = pWal->lockMask & ~( (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) ); for(ii=0; ii<SQLITE_SHM_NLOCK; ii++){ if( (S<<ii) & mUnlock ) walUnlockShared(pWal, ii); if( (E<<ii) & mUnlock ) walUnlockExclusive(pWal, ii, 1); |
︙ | ︙ | |||
67851 67852 67853 67854 67855 67856 67857 | rc = SQLITE_READONLY_RECOVERY; } }else{ int bWriteLock = pWal->writeLock; if( bWriteLock || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ | > > > > > | | 68653 68654 68655 68656 68657 68658 68659 68660 68661 68662 68663 68664 68665 68666 68667 68668 68669 68670 68671 68672 | rc = SQLITE_READONLY_RECOVERY; } }else{ int bWriteLock = pWal->writeLock; if( bWriteLock || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ /* If the write-lock was just obtained, set writeLock to 2 instead of ** the usual 1. This causes walIndexPage() to behave as if the ** write-lock were held (so that it allocates new pages as required), ** and walHandleException() to unlock the write-lock if a SEH exception ** is thrown. */ if( !bWriteLock ) pWal->writeLock = 2; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); if( badHdr ){ /* If the wal-index header is still malformed even while holding ** a WRITE lock, it can only mean that the header is corrupted and ** needs to be reconstructed. So run recovery to do exactly that. ** Disable blocking locks first. */ |
︙ | ︙ | |||
68636 68637 68638 68639 68640 68641 68642 | } /* ** Finish with a read transaction. All this does is release the ** read-lock. */ SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ | > | > > | 69443 69444 69445 69446 69447 69448 69449 69450 69451 69452 69453 69454 69455 69456 69457 69458 69459 69460 69461 | } /* ** Finish with a read transaction. All this does is release the ** read-lock. */ SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ #ifndef SQLITE_ENABLE_SETLK_TIMEOUT assert( pWal->writeLock==0 || pWal->readLock<0 ); #endif if( pWal->readLock>=0 ){ sqlite3WalEndWriteTransaction(pWal); walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); pWal->readLock = -1; } } /* ** Search the wal file for page pgno. If found, set *piRead to the frame that |
︙ | ︙ | |||
68830 68831 68832 68833 68834 68835 68836 | int rc; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT /* If the write-lock is already held, then it was obtained before the ** read-transaction was even opened, making this call a no-op. ** Return early. */ if( pWal->writeLock ){ | | | 69640 69641 69642 69643 69644 69645 69646 69647 69648 69649 69650 69651 69652 69653 69654 | int rc; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT /* If the write-lock is already held, then it was obtained before the ** read-transaction was even opened, making this call a no-op. ** Return early. */ if( pWal->writeLock ){ assert( !memcmp(&pWal->hdr,(void*)pWal->apWiData[0],sizeof(WalIndexHdr)) ); return SQLITE_OK; } #endif /* Cannot start a write transaction without first holding a read ** transaction. */ assert( pWal->readLock>=0 ); |
︙ | ︙ | |||
70279 70280 70281 70282 70283 70284 70285 70286 70287 70288 70289 70290 70291 70292 | ** root-node and 3 for all other internal nodes. ** ** If a tree that appears to be taller than this is encountered, it is ** assumed that the database is corrupt. */ #define BTCURSOR_MAX_DEPTH 20 /* ** A cursor is a pointer to a particular entry within a particular ** b-tree within a database file. ** ** The entry is identified by its MemPage and the index in ** MemPage.aCell[] of the entry. ** | > > > > > > | 71089 71090 71091 71092 71093 71094 71095 71096 71097 71098 71099 71100 71101 71102 71103 71104 71105 71106 71107 71108 | ** root-node and 3 for all other internal nodes. ** ** If a tree that appears to be taller than this is encountered, it is ** assumed that the database is corrupt. */ #define BTCURSOR_MAX_DEPTH 20 /* ** Maximum amount of storage local to a database page, regardless of ** page size. */ #define BT_MAX_LOCAL 65501 /* 65536 - 35 */ /* ** A cursor is a pointer to a particular entry within a particular ** b-tree within a database file. ** ** The entry is identified by its MemPage and the index in ** MemPage.aCell[] of the entry. ** |
︙ | ︙ | |||
70687 70688 70689 70690 70691 70692 70693 | ** Enter the mutexes in ascending order by BtShared pointer address ** to avoid the possibility of deadlock when two threads with ** two or more btrees in common both try to lock all their btrees ** at the same instant. */ static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ int i; | | | 71503 71504 71505 71506 71507 71508 71509 71510 71511 71512 71513 71514 71515 71516 71517 | ** Enter the mutexes in ascending order by BtShared pointer address ** to avoid the possibility of deadlock when two threads with ** two or more btrees in common both try to lock all their btrees ** at the same instant. */ static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ int i; u8 skipOk = 1; Btree *p; assert( sqlite3_mutex_held(db->mutex) ); for(i=0; i<db->nDb; i++){ p = db->aDb[i].pBt; if( p && p->sharable ){ sqlite3BtreeEnter(p); skipOk = 0; |
︙ | ︙ | |||
71833 71834 71835 71836 71837 71838 71839 | /* ** Provide flag hints to the cursor. */ SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); | | | 72649 72650 72651 72652 72653 72654 72655 72656 72657 72658 72659 72660 72661 72662 72663 | /* ** Provide flag hints to the cursor. */ SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); pCur->hints = (u8)x; } #ifndef SQLITE_OMIT_AUTOVACUUM /* ** Given a page number of a regular database page, return the page ** number for the pointer-map page that contains the entry for the |
︙ | ︙ | |||
72027 72028 72029 72030 72031 72032 72033 72034 | /* ** Given a record with nPayload bytes of payload stored within btree ** page pPage, return the number of bytes of payload stored locally. */ static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ int maxLocal; /* Maximum amount of payload held locally */ maxLocal = pPage->maxLocal; if( nPayload<=maxLocal ){ | > | | | | 72843 72844 72845 72846 72847 72848 72849 72850 72851 72852 72853 72854 72855 72856 72857 72858 72859 72860 72861 72862 72863 72864 72865 | /* ** Given a record with nPayload bytes of payload stored within btree ** page pPage, return the number of bytes of payload stored locally. */ static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ int maxLocal; /* Maximum amount of payload held locally */ maxLocal = pPage->maxLocal; assert( nPayload>=0 ); if( nPayload<=maxLocal ){ return (int)nPayload; }else{ int minLocal; /* Minimum amount of payload held locally */ int surplus; /* Overflow payload available for local storage */ minLocal = pPage->minLocal; surplus = (int)(minLocal +(nPayload - minLocal)%(pPage->pBt->usableSize-4)); return (surplus <= maxLocal) ? surplus : minLocal; } } /* ** The following routines are implementations of the MemPage.xParseCell() ** method. ** |
︙ | ︙ | |||
72144 72145 72146 72147 72148 72149 72150 72151 72152 72153 72154 | pIter++; pInfo->nKey = *(i64*)&iKey; pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); testcase( nPayload==(u32)pPage->maxLocal+1 ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ | > > | | 72961 72962 72963 72964 72965 72966 72967 72968 72969 72970 72971 72972 72973 72974 72975 72976 72977 72978 72979 72980 72981 | pIter++; pInfo->nKey = *(i64*)&iKey; pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); testcase( nPayload==(u32)pPage->maxLocal+1 ); assert( nPayload>=0 ); assert( pPage->maxLocal <= BT_MAX_LOCAL ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); if( pInfo->nSize<4 ) pInfo->nSize = 4; pInfo->nLocal = (u16)nPayload; }else{ btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); } } static void btreeParseCellPtrIndex( |
︙ | ︙ | |||
72181 72182 72183 72184 72185 72186 72187 72188 72189 72190 72191 | } pIter++; pInfo->nKey = nPayload; pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); testcase( nPayload==(u32)pPage->maxLocal+1 ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ | > > | | 73000 73001 73002 73003 73004 73005 73006 73007 73008 73009 73010 73011 73012 73013 73014 73015 73016 73017 73018 73019 73020 | } pIter++; pInfo->nKey = nPayload; pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); testcase( nPayload==(u32)pPage->maxLocal+1 ); assert( nPayload>=0 ); assert( pPage->maxLocal <= BT_MAX_LOCAL ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. */ pInfo->nSize = (u16)nPayload + (u16)(pIter - pCell); if( pInfo->nSize<4 ) pInfo->nSize = 4; pInfo->nLocal = (u16)nPayload; }else{ btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); } } static void btreeParseCell( |
︙ | ︙ | |||
72724 72725 72726 72727 72728 72729 72730 | ** ** Even though the freeblock list was checked by btreeComputeFreeSpace(), ** that routine will not detect overlap between cells or freeblocks. Nor ** does it detect cells or freeblocks that encroach into the reserved bytes ** at the end of the page. So do additional corruption checks inside this ** routine and return SQLITE_CORRUPT if any problems are found. */ | | | | | | | | | 73545 73546 73547 73548 73549 73550 73551 73552 73553 73554 73555 73556 73557 73558 73559 73560 73561 73562 73563 73564 73565 73566 | ** ** Even though the freeblock list was checked by btreeComputeFreeSpace(), ** that routine will not detect overlap between cells or freeblocks. Nor ** does it detect cells or freeblocks that encroach into the reserved bytes ** at the end of the page. So do additional corruption checks inside this ** routine and return SQLITE_CORRUPT if any problems are found. */ static int freeSpace(MemPage *pPage, int iStart, int iSize){ int iPtr; /* Address of ptr to next freeblock */ int iFreeBlk; /* Address of the next freeblock */ u8 hdr; /* Page header size. 0 or 100 */ int nFrag = 0; /* Reduction in fragmentation */ int iOrigSize = iSize; /* Original value of iSize */ int x; /* Offset to cell content area */ int iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ u8 *pTmp; /* Temporary ptr into data[] */ assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); |
︙ | ︙ | |||
72758 72759 72760 72761 72762 72763 72764 | while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ if( iFreeBlk<=iPtr ){ if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */ return SQLITE_CORRUPT_PAGE(pPage); } iPtr = iFreeBlk; } | | | | > | | 73579 73580 73581 73582 73583 73584 73585 73586 73587 73588 73589 73590 73591 73592 73593 73594 73595 73596 73597 73598 73599 73600 73601 73602 73603 73604 73605 73606 73607 73608 73609 73610 73611 73612 73613 73614 73615 73616 73617 73618 73619 73620 73621 73622 73623 73624 73625 73626 73627 73628 73629 73630 73631 73632 73633 73634 73635 73636 73637 73638 73639 73640 73641 73642 73643 73644 73645 73646 73647 73648 73649 73650 73651 | while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){ if( iFreeBlk<=iPtr ){ if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */ return SQLITE_CORRUPT_PAGE(pPage); } iPtr = iFreeBlk; } if( iFreeBlk>(int)pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ return SQLITE_CORRUPT_PAGE(pPage); } assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); /* At this point: ** iFreeBlk: First freeblock after iStart, or zero if none ** iPtr: The address of a pointer to iFreeBlk ** ** Check to see if iFreeBlk should be coalesced onto the end of iStart. */ if( iFreeBlk && iEnd+3>=iFreeBlk ){ nFrag = iFreeBlk - iEnd; if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage); iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]); if( iEnd > (int)pPage->pBt->usableSize ){ return SQLITE_CORRUPT_PAGE(pPage); } iSize = iEnd - iStart; iFreeBlk = get2byte(&data[iFreeBlk]); } /* If iPtr is another freeblock (that is, if iPtr is not the freelist ** pointer in the page header) then check to see if iStart should be ** coalesced onto the end of iPtr. */ if( iPtr>hdr+1 ){ int iPtrEnd = iPtr + get2byte(&data[iPtr+2]); if( iPtrEnd+3>=iStart ){ if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage); nFrag += iStart - iPtrEnd; iSize = iEnd - iPtr; iStart = iPtr; } } if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage); data[hdr+7] -= (u8)nFrag; } pTmp = &data[hdr+5]; x = get2byte(pTmp); if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ /* Overwrite deleted information with zeros when the secure_delete ** option is enabled */ memset(&data[iStart], 0, iSize); } if( iStart<=x ){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another ** freelist entry */ if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage); if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage); put2byte(&data[hdr+1], iFreeBlk); put2byte(&data[hdr+5], iEnd); }else{ /* Insert the new freeblock into the freelist */ put2byte(&data[iPtr], iStart); put2byte(&data[iStart], iFreeBlk); assert( iSize>=0 && iSize<=0xffff ); put2byte(&data[iStart+2], (u16)iSize); } pPage->nFree += iOrigSize; return SQLITE_OK; } /* ** Decode the flags byte (the first byte of the header) for a page |
︙ | ︙ | |||
73041 73042 73043 73044 73045 73046 73047 | ** the b-tree page type. */ if( decodeFlags(pPage, data[0]) ){ return SQLITE_CORRUPT_PAGE(pPage); } assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; | | | 73863 73864 73865 73866 73867 73868 73869 73870 73871 73872 73873 73874 73875 73876 73877 | ** the b-tree page type. */ if( decodeFlags(pPage, data[0]) ){ return SQLITE_CORRUPT_PAGE(pPage); } assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; pPage->cellOffset = (u16)(pPage->hdrOffset + 8 + pPage->childPtrSize); pPage->aCellIdx = data + pPage->childPtrSize + 8; pPage->aDataEnd = pPage->aData + pBt->pageSize; pPage->aDataOfst = pPage->aData + pPage->childPtrSize; /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ pPage->nCell = get2byte(&data[3]); if( pPage->nCell>MX_CELL(pBt) ){ |
︙ | ︙ | |||
73075 73076 73077 73078 73079 73080 73081 | /* ** Set up a raw page so that it looks like a database page holding ** no entries. */ static void zeroPage(MemPage *pPage, int flags){ unsigned char *data = pPage->aData; BtShared *pBt = pPage->pBt; | | | | | 73897 73898 73899 73900 73901 73902 73903 73904 73905 73906 73907 73908 73909 73910 73911 73912 73913 73914 73915 73916 73917 73918 73919 73920 73921 73922 73923 73924 73925 73926 73927 73928 73929 | /* ** Set up a raw page so that it looks like a database page holding ** no entries. */ static void zeroPage(MemPage *pPage, int flags){ unsigned char *data = pPage->aData; BtShared *pBt = pPage->pBt; int hdr = pPage->hdrOffset; int first; assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); assert( sqlite3PagerGetData(pPage->pDbPage) == data ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pBt->mutex) ); if( pBt->btsFlags & BTS_FAST_SECURE ){ memset(&data[hdr], 0, pBt->usableSize - hdr); } data[hdr] = (char)flags; first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8); memset(&data[hdr+1], 0, 4); data[hdr+7] = 0; put2byte(&data[hdr+5], pBt->usableSize); pPage->nFree = (u16)(pBt->usableSize - first); decodeFlags(pPage, flags); pPage->cellOffset = (u16)first; pPage->aDataEnd = &data[pBt->pageSize]; pPage->aCellIdx = &data[first]; pPage->aDataOfst = &data[pPage->childPtrSize]; pPage->nOverflow = 0; assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nCell = 0; |
︙ | ︙ | |||
73879 73880 73881 73882 73883 73884 73885 | */ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ int rc = SQLITE_OK; int x; BtShared *pBt = p->pBt; assert( nReserve>=0 && nReserve<=255 ); sqlite3BtreeEnter(p); | | | 74701 74702 74703 74704 74705 74706 74707 74708 74709 74710 74711 74712 74713 74714 74715 | */ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ int rc = SQLITE_OK; int x; BtShared *pBt = p->pBt; assert( nReserve>=0 && nReserve<=255 ); sqlite3BtreeEnter(p); pBt->nReserveWanted = (u8)nReserve; x = pBt->pageSize - pBt->usableSize; if( nReserve<x ) nReserve = x; if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ sqlite3BtreeLeave(p); return SQLITE_READONLY; } assert( nReserve>=0 && nReserve<=255 ); |
︙ | ︙ | |||
73985 73986 73987 73988 73989 73990 73991 | int b; if( p==0 ) return 0; sqlite3BtreeEnter(p); assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 ); assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); if( newFlag>=0 ){ p->pBt->btsFlags &= ~BTS_FAST_SECURE; | | | 74807 74808 74809 74810 74811 74812 74813 74814 74815 74816 74817 74818 74819 74820 74821 | int b; if( p==0 ) return 0; sqlite3BtreeEnter(p); assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 ); assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); if( newFlag>=0 ){ p->pBt->btsFlags &= ~BTS_FAST_SECURE; p->pBt->btsFlags |= (u16)(BTS_SECURE_DELETE*newFlag); } b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE; sqlite3BtreeLeave(p); return b; } /* |
︙ | ︙ | |||
78433 78434 78435 78436 78437 78438 78439 | if( pCArray->ixNx[k]<=i ){ k++; pSrcEnd = pCArray->apEnd[k]; } } /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ | > | | 79255 79256 79257 79258 79259 79260 79261 79262 79263 79264 79265 79266 79267 79268 79269 79270 | if( pCArray->ixNx[k]<=i ){ k++; pSrcEnd = pCArray->apEnd[k]; } } /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ assert( nCell < 10922 ); pPg->nCell = (u16)nCell; pPg->nOverflow = 0; put2byte(&aData[hdr+1], 0); put2byte(&aData[hdr+3], pPg->nCell); put2byte(&aData[hdr+5], pData - aData); aData[hdr+7] = 0x00; return SQLITE_OK; |
︙ | ︙ | |||
78680 78681 78682 78683 78684 78685 78686 | /* Append cells to the end of the page */ assert( nCell>=0 ); pCellptr = &pPg->aCellIdx[nCell*2]; if( pageInsertArray( pPg, pBegin, &pData, pCellptr, iNew+nCell, nNew-nCell, pCArray | > > | | > > | | 79503 79504 79505 79506 79507 79508 79509 79510 79511 79512 79513 79514 79515 79516 79517 79518 79519 79520 79521 79522 79523 | /* Append cells to the end of the page */ assert( nCell>=0 ); pCellptr = &pPg->aCellIdx[nCell*2]; if( pageInsertArray( pPg, pBegin, &pData, pCellptr, iNew+nCell, nNew-nCell, pCArray ) ){ goto editpage_fail; } assert( nNew < 10922 ); pPg->nCell = (u16)nNew; pPg->nOverflow = 0; put2byte(&aData[hdr+3], pPg->nCell); put2byte(&aData[hdr+5], pData - aData); #ifdef SQLITE_DEBUG for(i=0; i<nNew && !CORRUPT_DB; i++){ |
︙ | ︙ | |||
78991 78992 78993 78994 78995 78996 78997 | int rc = SQLITE_OK; /* The return code */ u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ int usableSpace; /* Bytes in pPage beyond the header */ int pageFlags; /* Value of pPage->aData[0] */ int iSpace1 = 0; /* First unused byte of aSpace1[] */ int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ | | | 79818 79819 79820 79821 79822 79823 79824 79825 79826 79827 79828 79829 79830 79831 79832 | int rc = SQLITE_OK; /* The return code */ u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ int usableSpace; /* Bytes in pPage beyond the header */ int pageFlags; /* Value of pPage->aData[0] */ int iSpace1 = 0; /* First unused byte of aSpace1[] */ int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ u64 szScratch; /* Size of scratch memory requested */ MemPage *apOld[NB]; /* pPage and up to two siblings */ MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ u8 *pRight; /* Location in parent of right-sibling pointer */ u8 *apDiv[NB-1]; /* Divider cells in pParent */ int cntNew[NB+2]; /* Index in b.paCell[] of cell after i-th page */ int cntOld[NB+2]; /* Old index in b.apCell[] */ int szNew[NB+2]; /* Combined size of cells placed on i-th page */ |
︙ | ︙ | |||
80276 80277 80278 80279 80280 80281 80282 | ** overwrite optimization. */ if( loc==0 ){ getCellInfo(pCur); if( pCur->info.nKey==pX->nKey ){ BtreePayload x2; x2.pData = pX->pKey; | | | 81103 81104 81105 81106 81107 81108 81109 81110 81111 81112 81113 81114 81115 81116 81117 | ** overwrite optimization. */ if( loc==0 ){ getCellInfo(pCur); if( pCur->info.nKey==pX->nKey ){ BtreePayload x2; x2.pData = pX->pKey; x2.nData = (int)pX->nKey; assert( pX->nKey<=0x7fffffff ); x2.nZero = 0; return btreeOverwriteCell(pCur, &x2); } } } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); |
︙ | ︙ | |||
80457 80458 80459 80460 80461 80462 80463 | u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ u32 nIn; /* Size of input buffer aIn[] */ u32 nRem; /* Bytes of data still to copy */ getCellInfo(pSrc); if( pSrc->info.nPayload<0x80 ){ | | | | | 81284 81285 81286 81287 81288 81289 81290 81291 81292 81293 81294 81295 81296 81297 81298 81299 81300 81301 81302 81303 81304 81305 81306 81307 81308 81309 81310 81311 81312 81313 81314 81315 81316 81317 81318 81319 81320 81321 81322 81323 | u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ u32 nIn; /* Size of input buffer aIn[] */ u32 nRem; /* Bytes of data still to copy */ getCellInfo(pSrc); if( pSrc->info.nPayload<0x80 ){ *(aOut++) = (u8)pSrc->info.nPayload; }else{ aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); } if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; if( aIn+nIn>pSrc->pPage->aDataEnd ){ return SQLITE_CORRUPT_PAGE(pSrc->pPage); } nRem = pSrc->info.nPayload; if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ memcpy(aOut, aIn, nIn); pBt->nPreformatSize = nIn + (int)(aOut - pBt->pTmpSpace); return SQLITE_OK; }else{ int rc = SQLITE_OK; Pager *pSrcPager = pSrc->pBt->pPager; u8 *pPgnoOut = 0; Pgno ovflIn = 0; DbPage *pPageIn = 0; MemPage *pPageOut = 0; u32 nOut; /* Size of output buffer aOut[] */ nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); pBt->nPreformatSize = (int)nOut + (int)(aOut - pBt->pTmpSpace); if( nOut<pSrc->info.nPayload ){ pPgnoOut = &aOut[nOut]; pBt->nPreformatSize += 4; } if( nRem>nIn ){ if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ |
︙ | ︙ | |||
83220 83221 83222 83223 83224 83225 83226 | ** ** A single int or real value always converts to the same strings. But ** many different strings can be converted into the same int or real. ** If a table contains a numeric value and an index is based on the ** corresponding string value, then it is important that the string be ** derived from the numeric value, not the other way around, to ensure ** that the index and table are consistent. See ticket | | | 84047 84048 84049 84050 84051 84052 84053 84054 84055 84056 84057 84058 84059 84060 84061 | ** ** A single int or real value always converts to the same strings. But ** many different strings can be converted into the same int or real. ** If a table contains a numeric value and an index is based on the ** corresponding string value, then it is important that the string be ** derived from the numeric value, not the other way around, to ensure ** that the index and table are consistent. See ticket ** https://sqlite.org/src/info/343634942dd54ab (2018-01-31) for ** an example. ** ** This routine looks at pMem to verify that if it has both a numeric ** representation and a string representation then the string rep has ** been derived from the numeric and not the other way around. It returns ** true if everything is ok and false if there is a problem. ** |
︙ | ︙ | |||
85583 85584 85585 85586 85587 85588 85589 | int p2, /* First argument register */ int p3, /* Register into which results are written */ int nArg, /* Number of argument */ const FuncDef *pFunc, /* The function to be invoked */ int eCallCtx /* Calling context */ ){ Vdbe *v = pParse->pVdbe; | < < | | 86410 86411 86412 86413 86414 86415 86416 86417 86418 86419 86420 86421 86422 86423 86424 86425 86426 86427 | int p2, /* First argument register */ int p3, /* Register into which results are written */ int nArg, /* Number of argument */ const FuncDef *pFunc, /* The function to be invoked */ int eCallCtx /* Calling context */ ){ Vdbe *v = pParse->pVdbe; int addr; sqlite3_context *pCtx; assert( v ); pCtx = sqlite3DbMallocRawNN(pParse->db, SZ_CONTEXT(nArg)); if( pCtx==0 ){ assert( pParse->db->mallocFailed ); freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); return 0; } pCtx->pOut = 0; pCtx->pFunc = (FuncDef*)pFunc; |
︙ | ︙ | |||
86446 86447 86448 86449 86450 86451 86452 86453 86454 86455 86456 86457 86458 86459 | /* ** If the previous opcode is an OP_Column that delivers results ** into register iDest, then add the OPFLAG_TYPEOFARG flag to that ** opcode. */ SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ VdbeOp *pOp = sqlite3VdbeGetLastOp(p); if( pOp->p3==iDest && pOp->opcode==OP_Column ){ pOp->p5 |= OPFLAG_TYPEOFARG; } } /* ** Change the P2 operand of instruction addr so that it points to | > > > | 87271 87272 87273 87274 87275 87276 87277 87278 87279 87280 87281 87282 87283 87284 87285 87286 87287 | /* ** If the previous opcode is an OP_Column that delivers results ** into register iDest, then add the OPFLAG_TYPEOFARG flag to that ** opcode. */ SQLITE_PRIVATE void sqlite3VdbeTypeofColumn(Vdbe *p, int iDest){ VdbeOp *pOp = sqlite3VdbeGetLastOp(p); #ifdef SQLITE_DEBUG while( pOp->opcode==OP_ReleaseReg ) pOp--; #endif if( pOp->p3==iDest && pOp->opcode==OP_Column ){ pOp->p5 |= OPFLAG_TYPEOFARG; } } /* ** Change the P2 operand of instruction addr so that it points to |
︙ | ︙ | |||
90664 90665 90666 90667 90668 90669 90670 | || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1) ); preupdate.v = v; preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; | > | | | | | | | 91492 91493 91494 91495 91496 91497 91498 91499 91500 91501 91502 91503 91504 91505 91506 91507 91508 91509 91510 91511 91512 91513 91514 91515 91516 91517 91518 91519 91520 91521 | || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1) ); preupdate.v = v; preupdate.pCsr = pCsr; preupdate.op = op; preupdate.iNewReg = iReg; preupdate.pKeyinfo = (KeyInfo*)&preupdate.keyinfoSpace; preupdate.pKeyinfo->db = db; preupdate.pKeyinfo->enc = ENC(db); preupdate.pKeyinfo->nKeyField = pTab->nCol; preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.pTab = pTab; preupdate.iBlobWrite = iBlobWrite; db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); db->pPreUpdate = 0; sqlite3DbFree(db, preupdate.aRecord); vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pUnpacked); vdbeFreeUnpacked(db, preupdate.pKeyinfo->nKeyField+1,preupdate.pNewUnpacked); sqlite3VdbeMemRelease(&preupdate.oldipk); if( preupdate.aNew ){ int i; for(i=0; i<pCsr->nField; i++){ sqlite3VdbeMemRelease(&preupdate.aNew[i]); } sqlite3DbNNFreeNN(db, preupdate.aNew); |
︙ | ︙ | |||
92509 92510 92511 92512 92513 92514 92515 | sqlite3_uint64 nData, void (*xDel)(void*), unsigned char enc ){ assert( xDel!=SQLITE_DYNAMIC ); if( enc!=SQLITE_UTF8 ){ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; | | | 93338 93339 93340 93341 93342 93343 93344 93345 93346 93347 93348 93349 93350 93351 93352 | sqlite3_uint64 nData, void (*xDel)(void*), unsigned char enc ){ assert( xDel!=SQLITE_DYNAMIC ); if( enc!=SQLITE_UTF8 ){ if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; nData &= ~(u64)1; } return bindText(pStmt, i, zData, nData, xDel, enc); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API int sqlite3_bind_text16( sqlite3_stmt *pStmt, int i, |
︙ | ︙ | |||
92917 92918 92919 92920 92921 92922 92923 | assert( p->pCsr->eCurType==CURTYPE_BTREE ); nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); aRec = sqlite3DbMallocRaw(db, nRec); if( !aRec ) goto preupdate_old_out; rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); if( rc==SQLITE_OK ){ | | | 93746 93747 93748 93749 93750 93751 93752 93753 93754 93755 93756 93757 93758 93759 93760 | assert( p->pCsr->eCurType==CURTYPE_BTREE ); nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); aRec = sqlite3DbMallocRaw(db, nRec); if( !aRec ) goto preupdate_old_out; rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); if( rc==SQLITE_OK ){ p->pUnpacked = vdbeUnpackRecord(p->pKeyinfo, nRec, aRec); if( !p->pUnpacked ) rc = SQLITE_NOMEM; } if( rc!=SQLITE_OK ){ sqlite3DbFree(db, aRec); goto preupdate_old_out; } p->aRecord = aRec; |
︙ | ︙ | |||
92982 92983 92984 92985 92986 92987 92988 | SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ PreUpdate *p; #ifdef SQLITE_ENABLE_API_ARMOR p = db!=0 ? db->pPreUpdate : 0; #else p = db->pPreUpdate; #endif | | | 93811 93812 93813 93814 93815 93816 93817 93818 93819 93820 93821 93822 93823 93824 93825 | SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ PreUpdate *p; #ifdef SQLITE_ENABLE_API_ARMOR p = db!=0 ? db->pPreUpdate : 0; #else p = db->pPreUpdate; #endif return (p ? p->pKeyinfo->nKeyField : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is designed to be called from within a pre-update callback ** only. It returns zero if the change that caused the callback was made |
︙ | ︙ | |||
93065 93066 93067 93068 93069 93070 93071 | /* For an INSERT, memory cell p->iNewReg contains the serialized record ** that is being inserted. Deserialize it. */ UnpackedRecord *pUnpack = p->pNewUnpacked; if( !pUnpack ){ Mem *pData = &p->v->aMem[p->iNewReg]; rc = ExpandBlob(pData); if( rc!=SQLITE_OK ) goto preupdate_new_out; | | | 93894 93895 93896 93897 93898 93899 93900 93901 93902 93903 93904 93905 93906 93907 93908 | /* For an INSERT, memory cell p->iNewReg contains the serialized record ** that is being inserted. Deserialize it. */ UnpackedRecord *pUnpack = p->pNewUnpacked; if( !pUnpack ){ Mem *pData = &p->v->aMem[p->iNewReg]; rc = ExpandBlob(pData); if( rc!=SQLITE_OK ) goto preupdate_new_out; pUnpack = vdbeUnpackRecord(p->pKeyinfo, pData->n, pData->z); if( !pUnpack ){ rc = SQLITE_NOMEM; goto preupdate_new_out; } p->pNewUnpacked = pUnpack; } pMem = &pUnpack->aMem[iStore]; |
︙ | ︙ | |||
93859 93860 93861 93862 93863 93864 93865 | ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. ** Cursor 2 is at Mem[p->nMem-2]. And so forth. */ Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; i64 nByte; VdbeCursor *pCx = 0; | | | | | 94688 94689 94690 94691 94692 94693 94694 94695 94696 94697 94698 94699 94700 94701 94702 94703 94704 | ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. ** Cursor 2 is at Mem[p->nMem-2]. And so forth. */ Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; i64 nByte; VdbeCursor *pCx = 0; nByte = SZ_VDBECURSOR(nField); assert( ROUND8(nByte)==nByte ); if( eCurType==CURTYPE_BTREE ) nByte += sqlite3BtreeCursorSize(); assert( iCur>=0 && iCur<p->nCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } |
︙ | ︙ | |||
93894 93895 93896 93897 93898 93899 93900 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); pCx->eCurType = eCurType; pCx->nField = nField; pCx->aOffset = &pCx->aType[nField]; if( eCurType==CURTYPE_BTREE ){ | > | < | 94723 94724 94725 94726 94727 94728 94729 94730 94731 94732 94733 94734 94735 94736 94737 94738 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); pCx->eCurType = eCurType; pCx->nField = nField; pCx->aOffset = &pCx->aType[nField]; if( eCurType==CURTYPE_BTREE ){ assert( ROUND8(SZ_VDBECURSOR(nField))==SZ_VDBECURSOR(nField) ); pCx->uc.pCursor = (BtCursor*)&pMem->z[SZ_VDBECURSOR(nField)]; sqlite3BtreeCursorZero(pCx->uc.pCursor); } return pCx; } /* ** The string in pRec is known to look like an integer and to have a |
︙ | ︙ | |||
94899 94900 94901 94902 94903 94904 94905 | if( pOp->p4.z ){ p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); } }else{ sqlite3VdbeError(p, "%s", pOp->p4.z); } pcx = (int)(pOp - aOp); | | | 95728 95729 95730 95731 95732 95733 95734 95735 95736 95737 95738 95739 95740 95741 95742 | if( pOp->p4.z ){ p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); } }else{ sqlite3VdbeError(p, "%s", pOp->p4.z); } pcx = (int)(pOp - aOp); sqlite3_log(pOp->p1, "abort at %d: %s; [%s]", pcx, p->zErrMsg, p->zSql); } rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); if( rc==SQLITE_BUSY ){ p->rc = SQLITE_BUSY; }else{ assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ); |
︙ | ︙ | |||
96225 96226 96227 96228 96229 96230 96231 | if( (pIn1->flags & MEM_Null)==0 ){ pOut->flags = MEM_Int; pOut->u.i = ~sqlite3VdbeIntValue(pIn1); } break; } | | > > > > > > | 97054 97055 97056 97057 97058 97059 97060 97061 97062 97063 97064 97065 97066 97067 97068 97069 97070 97071 97072 97073 97074 97075 97076 97077 97078 97079 97080 97081 97082 97083 97084 97085 97086 97087 97088 97089 | if( (pIn1->flags & MEM_Null)==0 ){ pOut->flags = MEM_Int; pOut->u.i = ~sqlite3VdbeIntValue(pIn1); } break; } /* Opcode: Once P1 P2 P3 * * ** ** Fall through to the next instruction the first time this opcode is ** encountered on each invocation of the byte-code program. Jump to P2 ** on the second and all subsequent encounters during the same invocation. ** ** Top-level programs determine first invocation by comparing the P1 ** operand against the P1 operand on the OP_Init opcode at the beginning ** of the program. If the P1 values differ, then fall through and make ** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are ** the same then take the jump. ** ** For subprograms, there is a bitmask in the VdbeFrame that determines ** whether or not the jump should be taken. The bitmask is necessary ** because the self-altering code trick does not work for recursive ** triggers. ** ** The P3 operand is not used directly by this opcode. However P3 is ** used by the code generator as follows: If this opcode is the start ** of a subroutine and that subroutine uses a Bloom filter, then P3 will ** be the register that holds that Bloom filter. See tag-202407032019 ** in the source code for implementation details. */ case OP_Once: { /* jump */ u32 iAddr; /* Address of this instruction */ assert( p->aOp[0].opcode==OP_Init ); if( p->pFrame ){ iAddr = (int)(pOp - p->aOp); if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){ |
︙ | ︙ | |||
97286 97287 97288 97289 97290 97291 97292 97293 97294 97295 97296 97297 97298 97299 | memcpy(zPayload, pRec->z, pRec->n); zPayload += pRec->n; } }else{ zHdr += sqlite3PutVarint(zHdr, serial_type); if( pRec->n ){ assert( pRec->z!=0 ); memcpy(zPayload, pRec->z, pRec->n); zPayload += pRec->n; } } if( pRec==pLast ) break; pRec++; } | > | 98121 98122 98123 98124 98125 98126 98127 98128 98129 98130 98131 98132 98133 98134 98135 | memcpy(zPayload, pRec->z, pRec->n); zPayload += pRec->n; } }else{ zHdr += sqlite3PutVarint(zHdr, serial_type); if( pRec->n ){ assert( pRec->z!=0 ); assert( pRec->z!=(const char*)sqlite3CtypeMap ); memcpy(zPayload, pRec->z, pRec->n); zPayload += pRec->n; } } if( pRec==pLast ) break; pRec++; } |
︙ | ︙ | |||
99637 99638 99639 99640 99641 99642 99643 | assert( pC->nullRow==0 ); assert( pC->uc.pCursor!=0 ); pCrsr = pC->uc.pCursor; /* The OP_RowData opcodes always follow OP_NotExists or ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions ** that might invalidate the cursor. | | | 100473 100474 100475 100476 100477 100478 100479 100480 100481 100482 100483 100484 100485 100486 100487 | assert( pC->nullRow==0 ); assert( pC->uc.pCursor!=0 ); pCrsr = pC->uc.pCursor; /* The OP_RowData opcodes always follow OP_NotExists or ** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions ** that might invalidate the cursor. ** If this were not the case, one of the following assert()s ** would fail. Should this ever change (because of changes in the code ** generator) then the fix would be to insert a call to ** sqlite3VdbeCursorMoveto(). */ assert( pC->deferredMoveto==0 ); assert( sqlite3BtreeCursorIsValid(pCrsr) ); |
︙ | ︙ | |||
101286 101287 101288 101289 101290 101291 101292 | /* Allocate space for (a) the context object and (n-1) extra pointers ** to append to the sqlite3_context.argv[1] array, and (b) a memory ** cell in which to store the accumulation. Be careful that the memory ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. ** ** Note: We could avoid this by using a regular memory cell from aMem[] for ** the accumulator, instead of allocating one here. */ | | | 102122 102123 102124 102125 102126 102127 102128 102129 102130 102131 102132 102133 102134 102135 102136 | /* Allocate space for (a) the context object and (n-1) extra pointers ** to append to the sqlite3_context.argv[1] array, and (b) a memory ** cell in which to store the accumulation. Be careful that the memory ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. ** ** Note: We could avoid this by using a regular memory cell from aMem[] for ** the accumulator, instead of allocating one here. */ nAlloc = ROUND8P( SZ_CONTEXT(n) ); pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); if( pCtx==0 ) goto no_mem; pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); pCtx->pMem = 0; |
︙ | ︙ | |||
102734 102735 102736 102737 102738 102739 102740 | #endif if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); } p->rc = rc; sqlite3SystemError(db, rc); testcase( sqlite3GlobalConfig.xLog!=0 ); | | | | 103570 103571 103572 103573 103574 103575 103576 103577 103578 103579 103580 103581 103582 103583 103584 103585 | #endif if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); } p->rc = rc; sqlite3SystemError(db, rc); testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(rc, "statement aborts at %d: %s; [%s]", (int)(pOp - aOp), p->zErrMsg, p->zSql); if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ db->flags |= SQLITE_CorruptRdOnly; } rc = SQLITE_ERROR; if( resetSchemaOnFault>0 ){ |
︙ | ︙ | |||
102944 102945 102946 102947 102948 102949 102950 102951 102952 102953 102954 102955 102956 102957 | ){ int nAttempt = 0; int iCol; /* Index of zColumn in row-record */ int rc = SQLITE_OK; char *zErr = 0; Table *pTab; Incrblob *pBlob = 0; Parse sParse; #ifdef SQLITE_ENABLE_API_ARMOR if( ppBlob==0 ){ return SQLITE_MISUSE_BKPT; } #endif | > | 103780 103781 103782 103783 103784 103785 103786 103787 103788 103789 103790 103791 103792 103793 103794 | ){ int nAttempt = 0; int iCol; /* Index of zColumn in row-record */ int rc = SQLITE_OK; char *zErr = 0; Table *pTab; Incrblob *pBlob = 0; int iDb; Parse sParse; #ifdef SQLITE_ENABLE_API_ARMOR if( ppBlob==0 ){ return SQLITE_MISUSE_BKPT; } #endif |
︙ | ︙ | |||
102989 102990 102991 102992 102993 102994 102995 | } #ifndef SQLITE_OMIT_VIEW if( pTab && IsView(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } #endif | | > > > | | 103826 103827 103828 103829 103830 103831 103832 103833 103834 103835 103836 103837 103838 103839 103840 103841 103842 103843 103844 103845 103846 103847 103848 103849 103850 103851 103852 103853 103854 | } #ifndef SQLITE_OMIT_VIEW if( pTab && IsView(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } #endif if( pTab==0 || ((iDb = sqlite3SchemaToIndex(db, pTab->pSchema))==1 && sqlite3OpenTempDatabase(&sParse)) ){ if( sParse.zErrMsg ){ sqlite3DbFree(db, zErr); zErr = sParse.zErrMsg; sParse.zErrMsg = 0; } rc = SQLITE_ERROR; sqlite3BtreeLeaveAll(db); goto blob_open_out; } pBlob->pTab = pTab; pBlob->zDb = db->aDb[iDb].zDbSName; /* Now search pTab for the exact column. */ iCol = sqlite3ColumnIndex(pTab, zColumn); if( iCol<0 ){ sqlite3DbFree(db, zErr); zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); rc = SQLITE_ERROR; |
︙ | ︙ | |||
103084 103085 103086 103087 103088 103089 103090 | /* blobSeekToRow() will initialize r[1] to the desired rowid */ {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */ {OP_Column, 0, 0, 1}, /* 3 */ {OP_ResultRow, 1, 0, 0}, /* 4 */ {OP_Halt, 0, 0, 0}, /* 5 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; | < | 103924 103925 103926 103927 103928 103929 103930 103931 103932 103933 103934 103935 103936 103937 | /* blobSeekToRow() will initialize r[1] to the desired rowid */ {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */ {OP_Column, 0, 0, 1}, /* 3 */ {OP_ResultRow, 1, 0, 0}, /* 4 */ {OP_Halt, 0, 0, 0}, /* 5 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; VdbeOp *aOp; sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, pTab->pSchema->schema_cookie, pTab->pSchema->iGeneration); sqlite3VdbeChangeP5(v, 1); assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed ); |
︙ | ︙ | |||
103662 103663 103664 103665 103666 103667 103668 | int iMemory; /* Offset of free space in list.aMemory */ int nMemory; /* Size of list.aMemory allocation in bytes */ u8 bUsePMA; /* True if one or more PMAs created */ u8 bUseThreads; /* True to use background threads */ u8 iPrev; /* Previous thread used to flush PMA */ u8 nTask; /* Size of aTask[] array */ u8 typeMask; | | > > > | 104501 104502 104503 104504 104505 104506 104507 104508 104509 104510 104511 104512 104513 104514 104515 104516 104517 104518 104519 | int iMemory; /* Offset of free space in list.aMemory */ int nMemory; /* Size of list.aMemory allocation in bytes */ u8 bUsePMA; /* True if one or more PMAs created */ u8 bUseThreads; /* True to use background threads */ u8 iPrev; /* Previous thread used to flush PMA */ u8 nTask; /* Size of aTask[] array */ u8 typeMask; SortSubtask aTask[FLEXARRAY]; /* One or more subtasks */ }; /* Size (in bytes) of a VdbeSorter object that works with N or fewer subtasks */ #define SZ_VDBESORTER(N) (offsetof(VdbeSorter,aTask)+(N)*sizeof(SortSubtask)) #define SORTER_TYPE_INTEGER 0x01 #define SORTER_TYPE_TEXT 0x02 /* ** An instance of the following object is used to read records out of a ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. |
︙ | ︙ | |||
104296 104297 104298 104299 104300 104301 104302 | #endif assert( pCsr->pKeyInfo ); assert( !pCsr->isEphemeral ); assert( pCsr->eCurType==CURTYPE_SORTER ); assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) < 0x7fffffff ); | | | | 105138 105139 105140 105141 105142 105143 105144 105145 105146 105147 105148 105149 105150 105151 105152 105153 | #endif assert( pCsr->pKeyInfo ); assert( !pCsr->isEphemeral ); assert( pCsr->eCurType==CURTYPE_SORTER ); assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) < 0x7fffffff ); szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField+1); sz = SZ_VDBESORTER(nWorker+1); pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); pCsr->uc.pSorter = pSorter; if( pSorter==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ Btree *pBt = db->aDb[0].pBt; |
︙ | ︙ | |||
104761 104762 104763 104764 104765 104766 104767 104768 104769 104770 104771 104772 104773 104774 | }else{ pNext = p->u.pNext; } p->u.pNext = 0; for(i=0; aSlot[i]; i++){ p = vdbeSorterMerge(pTask, p, aSlot[i]); aSlot[i] = 0; } aSlot[i] = p; p = pNext; } p = 0; | > > > > | 105603 105604 105605 105606 105607 105608 105609 105610 105611 105612 105613 105614 105615 105616 105617 105618 105619 105620 | }else{ pNext = p->u.pNext; } p->u.pNext = 0; for(i=0; aSlot[i]; i++){ p = vdbeSorterMerge(pTask, p, aSlot[i]); /* ,--Each aSlot[] holds twice as much as the previous. So we cannot use ** | up all 64 aSlots[] with only a 64-bit address space. ** v */ assert( i<ArraySize(aSlot) ); aSlot[i] = 0; } aSlot[i] = p; p = pNext; } p = 0; |
︙ | ︙ | |||
109535 109536 109537 109538 109539 109540 109541 | SQLITE_PRIVATE int sqlite3ResolveSelfReference( Parse *pParse, /* Parsing context */ Table *pTab, /* The table being referenced, or NULL */ int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */ Expr *pExpr, /* Expression to resolve. May be NULL. */ ExprList *pList /* Expression list to resolve. May be NULL. */ ){ | | > > | | | | | | | 110381 110382 110383 110384 110385 110386 110387 110388 110389 110390 110391 110392 110393 110394 110395 110396 110397 110398 110399 110400 110401 110402 110403 110404 110405 110406 110407 110408 110409 110410 110411 110412 110413 110414 110415 110416 110417 110418 | SQLITE_PRIVATE int sqlite3ResolveSelfReference( Parse *pParse, /* Parsing context */ Table *pTab, /* The table being referenced, or NULL */ int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */ Expr *pExpr, /* Expression to resolve. May be NULL. */ ExprList *pList /* Expression list to resolve. May be NULL. */ ){ SrcList *pSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ int rc; u8 srcSpace[SZ_SRCLIST_1]; /* Memory space for the fake SrcList */ assert( type==0 || pTab!=0 ); assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || type==NC_GenCol || pTab==0 ); memset(&sNC, 0, sizeof(sNC)); pSrc = (SrcList*)srcSpace; memset(pSrc, 0, SZ_SRCLIST_1); if( pTab ){ pSrc->nSrc = 1; pSrc->a[0].zName = pTab->zName; pSrc->a[0].pSTab = pTab; pSrc->a[0].iCursor = -1; if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){ /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP ** schema elements */ type |= NC_FromDDL; } } sNC.pParse = pParse; sNC.pSrcList = pSrc; sNC.ncFlags = type | NC_IsDDL; if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); return rc; } /************** End of resolve.c *********************************************/ |
︙ | ︙ | |||
111305 111306 111307 111308 111309 111310 111311 | ** argument. If an OOM condition is encountered, NULL is returned ** and the db->mallocFailed flag set. */ #ifndef SQLITE_OMIT_CTE SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ With *pRet = 0; if( p ){ | | | 112153 112154 112155 112156 112157 112158 112159 112160 112161 112162 112163 112164 112165 112166 112167 | ** argument. If an OOM condition is encountered, NULL is returned ** and the db->mallocFailed flag set. */ #ifndef SQLITE_OMIT_CTE SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ With *pRet = 0; if( p ){ sqlite3_int64 nByte = SZ_WITH(p->nCte); pRet = sqlite3DbMallocZero(db, nByte); if( pRet ){ int i; pRet->nCte = p->nCte; for(i=0; i<p->nCte; i++){ pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); |
︙ | ︙ | |||
111432 111433 111434 111435 111436 111437 111438 | ** called with a NULL argument. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ SrcList *pNew; int i; | < < | | 112280 112281 112282 112283 112284 112285 112286 112287 112288 112289 112290 112291 112292 112293 112294 112295 112296 | ** called with a NULL argument. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ SrcList *pNew; int i; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, SZ_SRCLIST(p->nSrc) ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ SrcItem *pNewItem = &pNew->a[i]; const SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->fg = pOldItem->fg; |
︙ | ︙ | |||
111498 111499 111500 111501 111502 111503 111504 | return pNew; } SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ IdList *pNew; int i; assert( db!=0 ); if( p==0 ) return 0; | | | 112344 112345 112346 112347 112348 112349 112350 112351 112352 112353 112354 112355 112356 112357 112358 | return pNew; } SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ IdList *pNew; int i; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, SZ_IDLIST(p->nId)); if( pNew==0 ) return 0; pNew->nId = p->nId; for(i=0; i<p->nId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; const struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); } |
︙ | ︙ | |||
111530 111531 111532 111533 111534 111535 111536 | pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); pNew->op = p->op; pNew->pNext = pNext; pNew->pPrior = 0; pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->iLimit = 0; pNew->iOffset = 0; | | | 112376 112377 112378 112379 112380 112381 112382 112383 112384 112385 112386 112387 112388 112389 112390 | pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); pNew->op = p->op; pNew->pNext = pNext; pNew->pPrior = 0; pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->iLimit = 0; pNew->iOffset = 0; pNew->selFlags = p->selFlags & ~(u32)SF_UsesEphemeral; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = sqlite3WithDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); |
︙ | ︙ | |||
111582 111583 111584 111585 111586 111587 111588 | SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( sqlite3 *db, /* Database handle. Used for memory allocation */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ struct ExprList_item *pItem; ExprList *pList; | | | < | 112428 112429 112430 112431 112432 112433 112434 112435 112436 112437 112438 112439 112440 112441 112442 112443 112444 112445 112446 112447 112448 112449 112450 112451 112452 112453 112454 112455 112456 112457 112458 112459 112460 112461 112462 | SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( sqlite3 *db, /* Database handle. Used for memory allocation */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ struct ExprList_item *pItem; ExprList *pList; pList = sqlite3DbMallocRawNN(db, SZ_EXPRLIST(4)); if( pList==0 ){ sqlite3ExprDelete(db, pExpr); return 0; } pList->nAlloc = 4; pList->nExpr = 1; pItem = &pList->a[0]; *pItem = zeroItem; pItem->pExpr = pExpr; return pList; } SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow( sqlite3 *db, /* Database handle. Used for memory allocation */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ struct ExprList_item *pItem; ExprList *pNew; pList->nAlloc *= 2; pNew = sqlite3DbRealloc(db, pList, SZ_EXPRLIST(pList->nAlloc)); if( pNew==0 ){ sqlite3ExprListDelete(db, pList); sqlite3ExprDelete(db, pExpr); return 0; }else{ pList = pNew; } |
︙ | ︙ | |||
113196 113197 113198 113199 113200 113201 113202 113203 113204 | testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); if( addrBloom ){ sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; if( dest.iSDParm2==0 ){ | > > | < | | 114041 114042 114043 114044 114045 114046 114047 114048 114049 114050 114051 114052 114053 114054 114055 114056 114057 114058 114059 114060 | testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); if( addrBloom ){ /* Remember that location of the Bloom filter in the P3 operand ** of the OP_Once that began this subroutine. tag-202407032019 */ sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; if( dest.iSDParm2==0 ){ /* If the Bloom filter won't actually be used, keep it small */ sqlite3VdbeGetOp(v, addrBloom)->p1 = 10; } } if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; } assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ |
︙ | ︙ | |||
113647 113648 113649 113650 113651 113652 113653 | }else{ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); assert( pOp->opcode==OP_Once || pParse->nErr ); | | | 114493 114494 114495 114496 114497 114498 114499 114500 114501 114502 114503 114504 114505 114506 114507 | }else{ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); assert( pOp->opcode==OP_Once || pParse->nErr ); if( pOp->opcode==OP_Once && pOp->p3>0 ){ /* tag-202407032019 */ assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, rLhs, nVector); VdbeCoverage(v); } } sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); |
︙ | ︙ | |||
114239 114240 114241 114242 114243 114244 114245 | return target; } return -1; /* Not found */ } /* | | | 115085 115086 115087 115088 115089 115090 115091 115092 115093 115094 115095 115096 115097 115098 115099 | return target; } return -1; /* Not found */ } /* ** Expression pExpr is guaranteed to be a TK_COLUMN or equivalent. This ** function checks the Parse.pIdxPartExpr list to see if this column ** can be replaced with a constant value. If so, it generates code to ** put the constant value in a register (ideally, but not necessarily, ** register iTarget) and returns the register number. ** ** Or, if the TK_COLUMN cannot be replaced by a constant, zero is ** returned. |
︙ | ︙ | |||
115496 115497 115498 115499 115500 115501 115502 | break; } case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); | > | < | 116342 116343 116344 116345 116346 116347 116348 116349 116350 116351 116352 116353 116354 116355 116356 116357 116358 116359 116360 | break; } case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); assert( regFree1==0 || regFree1==r1 ); if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverageIf(v, op==TK_ISNULL); VdbeCoverageIf(v, op==TK_NOTNULL); break; } case TK_BETWEEN: { testcase( jumpIfNull==0 ); exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull); break; } |
︙ | ︙ | |||
115671 115672 115673 115674 115675 115676 115677 | testcase( regFree1==0 ); testcase( regFree2==0 ); break; } case TK_ISNULL: case TK_NOTNULL: { r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); | > | < | 116517 116518 116519 116520 116521 116522 116523 116524 116525 116526 116527 116528 116529 116530 116531 116532 116533 116534 116535 | testcase( regFree1==0 ); testcase( regFree2==0 ); break; } case TK_ISNULL: case TK_NOTNULL: { r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); assert( regFree1==0 || regFree1==r1 ); if( regFree1 ) sqlite3VdbeTypeofColumn(v, r1); sqlite3VdbeAddOp2(v, op, r1, dest); testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); break; } case TK_BETWEEN: { testcase( jumpIfNull==0 ); exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull); break; } |
︙ | ︙ | |||
117480 117481 117482 117483 117484 117485 117486 | if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; pNew->nTabRef = 1; pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); | | | | 118326 118327 118328 118329 118330 118331 118332 118333 118334 118335 118336 118337 118338 118339 118340 118341 118342 118343 118344 118345 118346 | if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; pNew->nTabRef = 1; pNew->nCol = pTab->nCol; assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*(u32)nAlloc); pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); if( !pNew->aCol || !pNew->zName ){ assert( db->mallocFailed ); goto exit_begin_add_column; } memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*(size_t)pNew->nCol); for(i=0; i<pNew->nCol; i++){ Column *pCol = &pNew->aCol[i]; pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); pCol->hName = sqlite3StrIHash(pCol->zCnName); } assert( IsOrdinaryTable(pNew) ); pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); |
︙ | ︙ | |||
118085 118086 118087 118088 118089 118090 118091 118092 118093 118094 118095 118096 118097 118098 118099 | Parse *p, /* Memory to use for Parse object */ const char *zDb, /* Name of schema SQL belongs to */ sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ int bTemp /* True if SQL is from temp schema */ ){ int rc; sqlite3ParseObjectInit(p, db); if( zSql==0 ){ return SQLITE_NOMEM; } if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ return SQLITE_CORRUPT_BKPT; } | > > | > > > > > > > > > | 118931 118932 118933 118934 118935 118936 118937 118938 118939 118940 118941 118942 118943 118944 118945 118946 118947 118948 118949 118950 118951 118952 118953 118954 118955 118956 118957 118958 118959 118960 118961 118962 118963 118964 118965 118966 118967 118968 | Parse *p, /* Memory to use for Parse object */ const char *zDb, /* Name of schema SQL belongs to */ sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ int bTemp /* True if SQL is from temp schema */ ){ int rc; u64 flags; sqlite3ParseObjectInit(p, db); if( zSql==0 ){ return SQLITE_NOMEM; } if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ return SQLITE_CORRUPT_BKPT; } if( bTemp ){ db->init.iDb = 1; }else{ int iDb = sqlite3FindDbName(db, zDb); assert( iDb>=0 && iDb<=0xff ); db->init.iDb = (u8)iDb; } p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; flags = db->flags; testcase( (db->flags & SQLITE_Comments)==0 && strstr(zSql," /* ")!=0 ); db->flags |= SQLITE_Comments; rc = sqlite3RunParser(p, zSql); db->flags = flags; if( db->mallocFailed ) rc = SQLITE_NOMEM; if( rc==SQLITE_OK && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) ){ rc = SQLITE_CORRUPT_BKPT; } |
︙ | ︙ | |||
118160 118161 118162 118163 118164 118165 118166 | zQuot = sqlite3MPrintf(db, "\"%w\" ", zNew); if( zQuot==0 ){ return SQLITE_NOMEM; }else{ nQuot = sqlite3Strlen30(zQuot)-1; } | | | > | | > | | | > | | | 119017 119018 119019 119020 119021 119022 119023 119024 119025 119026 119027 119028 119029 119030 119031 119032 119033 119034 119035 119036 119037 119038 119039 119040 119041 119042 119043 119044 119045 119046 119047 119048 119049 119050 119051 119052 119053 119054 119055 119056 119057 119058 119059 119060 119061 119062 119063 119064 119065 119066 119067 119068 119069 119070 119071 119072 119073 119074 119075 119076 119077 119078 119079 119080 119081 119082 119083 | zQuot = sqlite3MPrintf(db, "\"%w\" ", zNew); if( zQuot==0 ){ return SQLITE_NOMEM; }else{ nQuot = sqlite3Strlen30(zQuot)-1; } assert( nQuot>=nNew && nSql>=0 && nNew>=0 ); zOut = sqlite3DbMallocZero(db, (u64)(nSql + pRename->nList*nQuot + 1)); }else{ assert( nSql>0 ); zOut = (char*)sqlite3DbMallocZero(db, (u64)(nSql*2+1) * 3); if( zOut ){ zBuf1 = &zOut[nSql*2+1]; zBuf2 = &zOut[nSql*4+2]; } } /* At this point pRename->pList contains a list of RenameToken objects ** corresponding to all tokens in the input SQL that must be replaced ** with the new column name, or with single-quoted versions of themselves. ** All that remains is to construct and return the edited SQL string. */ if( zOut ){ i64 nOut = nSql; assert( nSql>0 ); memcpy(zOut, zSql, (size_t)nSql); while( pRename->pList ){ int iOff; /* Offset of token to replace in zOut */ i64 nReplace; const char *zReplace; RenameToken *pBest = renameColumnTokenNext(pRename); if( zNew ){ if( bQuote==0 && sqlite3IsIdChar(*(u8*)pBest->t.z) ){ nReplace = nNew; zReplace = zNew; }else{ nReplace = nQuot; zReplace = zQuot; if( pBest->t.z[pBest->t.n]=='"' ) nReplace++; } }else{ /* Dequote the double-quoted token. Then requote it again, this time ** using single quotes. If the character immediately following the ** original token within the input SQL was a single quote ('), then ** add another space after the new, single-quoted version of the ** token. This is so that (SELECT "string"'alias') maps to ** (SELECT 'string' 'alias'), and not (SELECT 'string''alias'). */ memcpy(zBuf1, pBest->t.z, pBest->t.n); zBuf1[pBest->t.n] = 0; sqlite3Dequote(zBuf1); assert( nSql < 0x15555554 /* otherwise malloc would have failed */ ); sqlite3_snprintf((int)(nSql*2), zBuf2, "%Q%s", zBuf1, pBest->t.z[pBest->t.n]=='\'' ? " " : "" ); zReplace = zBuf2; nReplace = sqlite3Strlen30(zReplace); } iOff = (int)(pBest->t.z - zSql); if( pBest->t.n!=nReplace ){ memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], nOut - (iOff + pBest->t.n) ); nOut += nReplace - pBest->t.n; zOut[nOut] = '\0'; } |
︙ | ︙ | |||
118235 118236 118237 118238 118239 118240 118241 118242 118243 118244 118245 | return rc; } /* ** Set all pEList->a[].fg.eEName fields in the expression-list to val. */ static void renameSetENames(ExprList *pEList, int val){ if( pEList ){ int i; for(i=0; i<pEList->nExpr; i++){ assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); | > | | 119095 119096 119097 119098 119099 119100 119101 119102 119103 119104 119105 119106 119107 119108 119109 119110 119111 119112 119113 119114 | return rc; } /* ** Set all pEList->a[].fg.eEName fields in the expression-list to val. */ static void renameSetENames(ExprList *pEList, int val){ assert( val==ENAME_NAME || val==ENAME_TAB || val==ENAME_SPAN ); if( pEList ){ int i; for(i=0; i<pEList->nExpr; i++){ assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME ); pEList->a[i].fg.eEName = val&0x3; } } } /* ** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming ** it was read from the schema of database zDb. Return SQLITE_OK if |
︙ | ︙ | |||
118496 118497 118498 118499 118500 118501 118502 | sWalker.u.pRename = &sCtx; sCtx.pTab = pTab; if( rc!=SQLITE_OK ) goto renameColumnFunc_done; if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; | | | 119357 119358 119359 119360 119361 119362 119363 119364 119365 119366 119367 119368 119369 119370 119371 | sWalker.u.pRename = &sCtx; sCtx.pTab = pTab; if( rc!=SQLITE_OK ) goto renameColumnFunc_done; if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; pSelect->selFlags &= ~(u32)SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); if( rc==SQLITE_OK ){ sqlite3WalkSelect(&sWalker, pSelect); } if( rc!=SQLITE_OK ) goto renameColumnFunc_done; |
︙ | ︙ | |||
118714 118715 118716 118717 118718 118719 118720 | if( isLegacy==0 ){ Select *pSelect = pTab->u.view.pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; assert( pSelect->selFlags & SF_View ); | | | 119575 119576 119577 119578 119579 119580 119581 119582 119583 119584 119585 119586 119587 119588 119589 | if( isLegacy==0 ){ Select *pSelect = pTab->u.view.pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; assert( pSelect->selFlags & SF_View ); pSelect->selFlags &= ~(u32)SF_View; sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); if( sParse.nErr ){ rc = sParse.rc; }else{ sqlite3WalkSelect(&sWalker, pTab->u.view.pSelect); } } |
︙ | ︙ | |||
118887 118888 118889 118890 118891 118892 118893 | sWalker.xExprCallback = renameQuotefixExprCb; sWalker.xSelectCallback = renameColumnSelectCb; sWalker.u.pRename = &sCtx; if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; | | | 119748 119749 119750 119751 119752 119753 119754 119755 119756 119757 119758 119759 119760 119761 119762 | sWalker.xExprCallback = renameQuotefixExprCb; sWalker.xSelectCallback = renameColumnSelectCb; sWalker.u.pRename = &sCtx; if( sParse.pNewTable ){ if( IsView(sParse.pNewTable) ){ Select *pSelect = sParse.pNewTable->u.view.pSelect; pSelect->selFlags &= ~(u32)SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); if( rc==SQLITE_OK ){ sqlite3WalkSelect(&sWalker, pSelect); } }else{ |
︙ | ︙ | |||
118986 118987 118988 118989 118990 118991 118992 | #endif UNUSED_PARAMETER(NotUsed); if( zDb && zInput ){ int rc; Parse sParse; | | | | 119847 119848 119849 119850 119851 119852 119853 119854 119855 119856 119857 119858 119859 119860 119861 119862 119863 119864 | #endif UNUSED_PARAMETER(NotUsed); if( zDb && zInput ){ int rc; Parse sParse; u64 flags = db->flags; if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL); rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); db->flags = flags; if( rc==SQLITE_OK ){ if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; sqlite3SelectPrep(&sParse, sParse.pNewTable->u.view.pSelect, &sNC); if( sParse.nErr ) rc = sParse.rc; |
︙ | ︙ | |||
119709 119710 119711 119712 119713 119714 119715 | sqlite3_result_error_nomem(context); return; } p->db = db; p->nEst = sqlite3_value_int64(argv[2]); p->nRow = 0; | | | 120570 120571 120572 120573 120574 120575 120576 120577 120578 120579 120580 120581 120582 120583 120584 | sqlite3_result_error_nomem(context); return; } p->db = db; p->nEst = sqlite3_value_int64(argv[2]); p->nRow = 0; p->nLimit = sqlite3_value_int(argv[3]); p->nCol = nCol; p->nKeyCol = nKeyCol; p->nSkipAhead = 0; p->current.anDLt = (tRowcnt*)&p[1]; #ifdef SQLITE_ENABLE_STAT4 p->current.anEq = &p->current.anDLt[nColUp]; |
︙ | ︙ | |||
121518 121519 121520 121521 121522 121523 121524 121525 121526 121527 121528 121529 121530 121531 | ** remove the entry from the db->aDb[] array. i.e. put everything back the ** way we found it. */ if( rc==SQLITE_OK ){ sqlite3BtreeEnterAll(db); db->init.iDb = 0; db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); if( !REOPEN_AS_MEMDB(db) ){ rc = sqlite3Init(db, &zErrDyn); } sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } if( rc ){ | > > > > > > > | 122379 122380 122381 122382 122383 122384 122385 122386 122387 122388 122389 122390 122391 122392 122393 122394 122395 122396 122397 122398 122399 | ** remove the entry from the db->aDb[] array. i.e. put everything back the ** way we found it. */ if( rc==SQLITE_OK ){ sqlite3BtreeEnterAll(db); db->init.iDb = 0; db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); #ifdef SQLITE_ENABLE_SETLK_TIMEOUT if( db->setlkFlags & SQLITE_SETLK_BLOCK_ON_CONNECT ){ int val = 1; sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pNew->pBt)); sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, &val); } #endif if( !REOPEN_AS_MEMDB(db) ){ rc = sqlite3Init(db, &zErrDyn); } sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } if( rc ){ |
︙ | ︙ | |||
123239 123240 123241 123242 123243 123244 123245 | /* ** Convert an table column number into a index column number. That is, ** for the column iCol in the table (as defined by the CREATE TABLE statement) ** find the (first) offset of that column in index pIdx. Or return -1 ** if column iCol is not used in index pIdx. */ | | > > > > | > > | 124107 124108 124109 124110 124111 124112 124113 124114 124115 124116 124117 124118 124119 124120 124121 124122 124123 124124 124125 124126 124127 124128 124129 124130 | /* ** Convert an table column number into a index column number. That is, ** for the column iCol in the table (as defined by the CREATE TABLE statement) ** find the (first) offset of that column in index pIdx. Or return -1 ** if column iCol is not used in index pIdx. */ SQLITE_PRIVATE int sqlite3TableColumnToIndex(Index *pIdx, int iCol){ int i; i16 iCol16; assert( iCol>=(-1) && iCol<=SQLITE_MAX_COLUMN ); assert( pIdx->nColumn<=SQLITE_MAX_COLUMN+1 ); iCol16 = iCol; for(i=0; i<pIdx->nColumn; i++){ if( iCol16==pIdx->aiColumn[i] ){ return i; } } return -1; } #ifndef SQLITE_OMIT_GENERATED_COLUMNS /* Convert a storage column number into a table column number. ** |
︙ | ︙ | |||
124339 124340 124341 124342 124343 124344 124345 | return zStmt; } /* ** Resize an Index object to hold N columns total. Return SQLITE_OK ** on success and SQLITE_NOMEM on an OOM error. */ | | | > > > > > | | | 125213 125214 125215 125216 125217 125218 125219 125220 125221 125222 125223 125224 125225 125226 125227 125228 125229 125230 125231 125232 125233 125234 125235 125236 125237 125238 125239 125240 125241 125242 125243 125244 125245 125246 125247 125248 125249 125250 125251 | return zStmt; } /* ** Resize an Index object to hold N columns total. Return SQLITE_OK ** on success and SQLITE_NOMEM on an OOM error. */ static int resizeIndexObject(Parse *pParse, Index *pIdx, int N){ char *zExtra; u64 nByte; sqlite3 *db; if( pIdx->nColumn>=N ) return SQLITE_OK; db = pParse->db; assert( N>0 ); assert( N <= SQLITE_MAX_COLUMN*2 /* tag-20250221-1 */ ); testcase( N==2*pParse->db->aLimit[SQLITE_LIMIT_COLUMN] ); assert( pIdx->isResized==0 ); nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*(u64)N; zExtra = sqlite3DbMallocZero(db, nByte); if( zExtra==0 ) return SQLITE_NOMEM_BKPT; memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); pIdx->azColl = (const char**)zExtra; zExtra += sizeof(char*)*N; memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1)); pIdx->aiRowLogEst = (LogEst*)zExtra; zExtra += sizeof(LogEst)*N; memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn); pIdx->aiColumn = (i16*)zExtra; zExtra += sizeof(i16)*N; memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn); pIdx->aSortOrder = (u8*)zExtra; pIdx->nColumn = (u16)N; /* See tag-20250221-1 above for proof of safety */ pIdx->isResized = 1; return SQLITE_OK; } /* ** Estimate the total row width for a table. */ |
︙ | ︙ | |||
124612 124613 124614 124615 124616 124617 124618 | } } if( n==0 ){ /* This index is a superset of the primary key */ pIdx->nColumn = pIdx->nKeyCol; continue; } | | | | | 125491 125492 125493 125494 125495 125496 125497 125498 125499 125500 125501 125502 125503 125504 125505 125506 125507 125508 125509 125510 125511 125512 125513 125514 125515 125516 125517 125518 125519 125520 125521 125522 125523 125524 125525 125526 125527 125528 125529 | } } if( n==0 ){ /* This index is a superset of the primary key */ pIdx->nColumn = pIdx->nKeyCol; continue; } if( resizeIndexObject(pParse, pIdx, pIdx->nKeyCol+n) ) return; for(i=0, j=pIdx->nKeyCol; i<nPk; i++){ if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); pIdx->aiColumn[j] = pPk->aiColumn[i]; pIdx->azColl[j] = pPk->azColl[i]; if( pPk->aSortOrder[i] ){ /* See ticket https://sqlite.org/src/info/bba7b69f9849b5bf */ pIdx->bAscKeyBug = 1; } j++; } } assert( pIdx->nColumn>=pIdx->nKeyCol+n ); assert( pIdx->nColumn>=j ); } /* Add all table columns to the PRIMARY KEY index */ nExtra = 0; for(i=0; i<pTab->nCol; i++){ if( !hasColumn(pPk->aiColumn, nPk, i) && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++; } if( resizeIndexObject(pParse, pPk, nPk+nExtra) ) return; for(i=0, j=nPk; i<pTab->nCol; i++){ if( !hasColumn(pPk->aiColumn, j, i) && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ assert( j<pPk->nColumn ); pPk->aiColumn[j] = i; pPk->azColl[j] = sqlite3StrBINARY; |
︙ | ︙ | |||
125794 125795 125796 125797 125798 125799 125800 | sqlite3ErrorMsg(pParse, "number of columns in foreign key does not match the number of " "columns in the referenced table"); goto fk_end; }else{ nCol = pFromCol->nExpr; } | | | 126673 126674 126675 126676 126677 126678 126679 126680 126681 126682 126683 126684 126685 126686 126687 | sqlite3ErrorMsg(pParse, "number of columns in foreign key does not match the number of " "columns in the referenced table"); goto fk_end; }else{ nCol = pFromCol->nExpr; } nByte = SZ_FKEY(nCol) + pTo->n + 1; if( pToCol ){ for(i=0; i<pToCol->nExpr; i++){ nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; } } pFKey = sqlite3DbMallocZero(db, nByte ); if( pFKey==0 ){ |
︙ | ︙ | |||
125996 125997 125998 125999 126000 126001 126002 | sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); if( !pIndex->bAscKeyBug ){ /* This OP_SeekEnd opcode makes index insert for a REINDEX go much ** faster by avoiding unnecessary seeks. But the optimization does ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables ** with DESC primary keys, since those indexes have there keys in ** a different order from the main table. | | | 126875 126876 126877 126878 126879 126880 126881 126882 126883 126884 126885 126886 126887 126888 126889 | sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); if( !pIndex->bAscKeyBug ){ /* This OP_SeekEnd opcode makes index insert for a REINDEX go much ** faster by avoiding unnecessary seeks. But the optimization does ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables ** with DESC primary keys, since those indexes have there keys in ** a different order from the main table. ** See ticket: https://sqlite.org/src/info/bba7b69f9849b5bf */ sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); |
︙ | ︙ | |||
126020 126021 126022 126023 126024 126025 126026 | ** ** Increase the allocation size to provide an extra nExtra bytes ** of 8-byte aligned space after the Index object and return a ** pointer to this extra space in *ppExtra. */ SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( sqlite3 *db, /* Database connection */ | | > > | | | 126899 126900 126901 126902 126903 126904 126905 126906 126907 126908 126909 126910 126911 126912 126913 126914 126915 126916 126917 126918 126919 126920 126921 126922 126923 126924 126925 126926 126927 126928 126929 126930 126931 126932 126933 126934 126935 | ** ** Increase the allocation size to provide an extra nExtra bytes ** of 8-byte aligned space after the Index object and return a ** pointer to this extra space in *ppExtra. */ SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( sqlite3 *db, /* Database connection */ int nCol, /* Total number of columns in the index */ int nExtra, /* Number of bytes of extra space to alloc */ char **ppExtra /* Pointer to the "extra" space */ ){ Index *p; /* Allocated index object */ i64 nByte; /* Bytes of space for Index object + arrays */ assert( nCol <= 2*db->aLimit[SQLITE_LIMIT_COLUMN] ); nByte = ROUND8(sizeof(Index)) + /* Index structure */ ROUND8(sizeof(char*)*nCol) + /* Index.azColl */ ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ sizeof(i16)*nCol + /* Index.aiColumn */ sizeof(u8)*nCol); /* Index.aSortOrder */ p = sqlite3DbMallocZero(db, nByte + nExtra); if( p ){ char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); p->aiRowLogEst = (LogEst*)pExtra; pExtra += sizeof(LogEst)*(nCol+1); p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol; p->aSortOrder = (u8*)pExtra; assert( nCol>0 ); p->nColumn = (u16)nCol; p->nKeyCol = (u16)(nCol - 1); *ppExtra = ((char*)p) + nByte; } return p; } /* ** If expression list pList contains an expression that was parsed with |
︙ | ︙ | |||
126378 126379 126380 126381 126382 126383 126384 126385 126386 126387 126388 126389 126390 126391 | pIndex->uniqNotNull = 0; pIndex->bHasExpr = 1; }else{ j = pCExpr->iColumn; assert( j<=0x7fff ); if( j<0 ){ j = pTab->iPKey; }else{ if( pTab->aCol[j].notNull==0 ){ pIndex->uniqNotNull = 0; } if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ pIndex->bHasVCol = 1; pIndex->bHasExpr = 1; | > | 127259 127260 127261 127262 127263 127264 127265 127266 127267 127268 127269 127270 127271 127272 127273 | pIndex->uniqNotNull = 0; pIndex->bHasExpr = 1; }else{ j = pCExpr->iColumn; assert( j<=0x7fff ); if( j<0 ){ j = pTab->iPKey; pIndex->bIdxRowid = 1; }else{ if( pTab->aCol[j].notNull==0 ){ pIndex->uniqNotNull = 0; } if( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ){ pIndex->bHasVCol = 1; pIndex->bHasExpr = 1; |
︙ | ︙ | |||
126851 126852 126853 126854 126855 126856 126857 | ** ** A new IdList is returned, or NULL if malloc() fails. */ SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ sqlite3 *db = pParse->db; int i; if( pList==0 ){ | | | < | 127733 127734 127735 127736 127737 127738 127739 127740 127741 127742 127743 127744 127745 127746 127747 127748 127749 127750 127751 | ** ** A new IdList is returned, or NULL if malloc() fails. */ SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ sqlite3 *db = pParse->db; int i; if( pList==0 ){ pList = sqlite3DbMallocZero(db, SZ_IDLIST(1)); if( pList==0 ) return 0; }else{ IdList *pNew; pNew = sqlite3DbRealloc(db, pList, SZ_IDLIST(pList->nId+1)); if( pNew==0 ){ sqlite3IdListDelete(db, pList); return 0; } pList = pNew; } i = pList->nId++; |
︙ | ︙ | |||
126955 126956 126957 126958 126959 126960 126961 | if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){ sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", SQLITE_MAX_SRCLIST); return 0; } if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; | | < | 127836 127837 127838 127839 127840 127841 127842 127843 127844 127845 127846 127847 127848 127849 127850 | if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){ sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", SQLITE_MAX_SRCLIST); return 0; } if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; pNew = sqlite3DbRealloc(db, pSrc, SZ_SRCLIST(nAlloc)); if( pNew==0 ){ assert( db->mallocFailed ); return 0; } pSrc = pNew; pSrc->nAlloc = nAlloc; } |
︙ | ︙ | |||
127031 127032 127033 127034 127035 127036 127037 | SrcItem *pItem; sqlite3 *db; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ assert( pParse!=0 ); assert( pParse->db!=0 ); db = pParse->db; if( pList==0 ){ | | | 127911 127912 127913 127914 127915 127916 127917 127918 127919 127920 127921 127922 127923 127924 127925 | SrcItem *pItem; sqlite3 *db; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ assert( pParse!=0 ); assert( pParse->db!=0 ); db = pParse->db; if( pList==0 ){ pList = sqlite3DbMallocRawNN(pParse->db, SZ_SRCLIST(1)); if( pList==0 ) return 0; pList->nAlloc = 1; pList->nSrc = 1; memset(&pList->a[0], 0, sizeof(pList->a[0])); pList->a[0].iCursor = -1; }else{ SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc); |
︙ | ︙ | |||
127917 127918 127919 127920 127921 127922 127923 | if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); } } } if( pWith ){ | < | | | 128797 128798 128799 128800 128801 128802 128803 128804 128805 128806 128807 128808 128809 128810 128811 128812 128813 | if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); } } } if( pWith ){ pNew = sqlite3DbRealloc(db, pWith, SZ_WITH(pWith->nCte+1)); }else{ pNew = sqlite3DbMallocZero(db, SZ_WITH(1)); } assert( (pNew!=0 && zName!=0) || db->mallocFailed ); if( db->mallocFailed ){ sqlite3CteDelete(db, pCte); pNew = pWith; }else{ |
︙ | ︙ | |||
130628 130629 130630 130631 130632 130633 130634 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /* ** Append to pStr text that is the SQL literal representation of the ** value contained in pValue. */ | | | 131507 131508 131509 131510 131511 131512 131513 131514 131515 131516 131517 131518 131519 131520 131521 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /* ** Append to pStr text that is the SQL literal representation of the ** value contained in pValue. */ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue, int bEscape){ /* As currently implemented, the string must be initially empty. ** we might relax this requirement in the future, but that will ** require enhancements to the implementation. */ assert( pStr!=0 && pStr->nChar==0 ); switch( sqlite3_value_type(pValue) ){ case SQLITE_FLOAT: { |
︙ | ︙ | |||
130676 130677 130678 130679 130680 130681 130682 | zText[1] = '\''; pStr->nChar = nBlob*2 + 3; } break; } case SQLITE_TEXT: { const unsigned char *zArg = sqlite3_value_text(pValue); | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 131555 131556 131557 131558 131559 131560 131561 131562 131563 131564 131565 131566 131567 131568 131569 131570 131571 131572 131573 131574 131575 131576 131577 131578 131579 131580 131581 131582 131583 131584 131585 131586 131587 131588 131589 131590 131591 131592 131593 131594 131595 131596 131597 131598 131599 131600 131601 131602 131603 131604 131605 131606 131607 131608 131609 131610 131611 131612 131613 131614 131615 131616 131617 131618 131619 131620 131621 131622 131623 131624 131625 131626 131627 131628 131629 131630 131631 131632 131633 131634 131635 131636 131637 131638 131639 131640 131641 131642 131643 131644 131645 131646 131647 131648 131649 131650 131651 131652 131653 131654 131655 131656 131657 131658 131659 131660 131661 131662 131663 131664 131665 131666 131667 131668 131669 131670 131671 131672 131673 131674 131675 131676 131677 131678 131679 131680 131681 131682 131683 131684 131685 131686 131687 131688 131689 131690 131691 131692 131693 131694 131695 131696 131697 131698 131699 | zText[1] = '\''; pStr->nChar = nBlob*2 + 3; } break; } case SQLITE_TEXT: { const unsigned char *zArg = sqlite3_value_text(pValue); sqlite3_str_appendf(pStr, bEscape ? "%#Q" : "%Q", zArg); break; } default: { assert( sqlite3_value_type(pValue)==SQLITE_NULL ); sqlite3_str_append(pStr, "NULL", 4); break; } } } /* ** Return true if z[] begins with N hexadecimal digits, and write ** a decoding of those digits into *pVal. Or return false if any ** one of the first N characters in z[] is not a hexadecimal digit. */ static int isNHex(const char *z, int N, u32 *pVal){ int i; int v = 0; for(i=0; i<N; i++){ if( !sqlite3Isxdigit(z[i]) ) return 0; v = (v<<4) + sqlite3HexToInt(z[i]); } *pVal = v; return 1; } /* ** Implementation of the UNISTR() function. ** ** This is intended to be a work-alike of the UNISTR() function in ** PostgreSQL. Quoting from the PG documentation (PostgreSQL 17 - ** scraped on 2025-02-22): ** ** Evaluate escaped Unicode characters in the argument. Unicode ** characters can be specified as \XXXX (4 hexadecimal digits), ** \+XXXXXX (6 hexadecimal digits), \uXXXX (4 hexadecimal digits), ** or \UXXXXXXXX (8 hexadecimal digits). To specify a backslash, ** write two backslashes. All other characters are taken literally. */ static void unistrFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ char *zOut; const char *zIn; int nIn; int i, j, n; u32 v; assert( argc==1 ); UNUSED_PARAMETER( argc ); zIn = (const char*)sqlite3_value_text(argv[0]); if( zIn==0 ) return; nIn = sqlite3_value_bytes(argv[0]); zOut = sqlite3_malloc64(nIn+1); if( zOut==0 ){ sqlite3_result_error_nomem(context); return; } i = j = 0; while( i<nIn ){ char *z = strchr(&zIn[i],'\\'); if( z==0 ){ n = nIn - i; memmove(&zOut[j], &zIn[i], n); j += n; break; } n = z - &zIn[i]; if( n>0 ){ memmove(&zOut[j], &zIn[i], n); j += n; i += n; } if( zIn[i+1]=='\\' ){ i += 2; zOut[j++] = '\\'; }else if( sqlite3Isxdigit(zIn[i+1]) ){ if( !isNHex(&zIn[i+1], 4, &v) ) goto unistr_error; i += 5; j += sqlite3AppendOneUtf8Character(&zOut[j], v); }else if( zIn[i+1]=='+' ){ if( !isNHex(&zIn[i+2], 6, &v) ) goto unistr_error; i += 8; j += sqlite3AppendOneUtf8Character(&zOut[j], v); }else if( zIn[i+1]=='u' ){ if( !isNHex(&zIn[i+2], 4, &v) ) goto unistr_error; i += 6; j += sqlite3AppendOneUtf8Character(&zOut[j], v); }else if( zIn[i+1]=='U' ){ if( !isNHex(&zIn[i+2], 8, &v) ) goto unistr_error; i += 10; j += sqlite3AppendOneUtf8Character(&zOut[j], v); }else{ goto unistr_error; } } zOut[j] = 0; sqlite3_result_text64(context, zOut, j, sqlite3_free, SQLITE_UTF8); return; unistr_error: sqlite3_free(zOut); sqlite3_result_error(context, "invalid Unicode escape", -1); return; } /* ** Implementation of the QUOTE() function. ** ** The quote(X) function returns the text of an SQL literal which is the ** value of its argument suitable for inclusion into an SQL statement. ** Strings are surrounded by single-quotes with escapes on interior quotes ** as needed. BLOBs are encoded as hexadecimal literals. Strings with ** embedded NUL characters cannot be represented as string literals in SQL ** and hence the returned string literal is truncated prior to the first NUL. ** ** If sqlite3_user_data() is non-zero, then the UNISTR_QUOTE() function is ** implemented instead. The difference is that UNISTR_QUOTE() uses the ** UNISTR() function to escape control characters. */ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3_str str; sqlite3 *db = sqlite3_context_db_handle(context); assert( argc==1 ); UNUSED_PARAMETER(argc); sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); sqlite3QuoteValue(&str,argv[0],SQLITE_PTR_TO_INT(sqlite3_user_data(context))); sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, SQLITE_DYNAMIC); if( str.accError!=SQLITE_OK ){ sqlite3_result_null(context); sqlite3_result_error_code(context, str.accError); } } |
︙ | ︙ | |||
131354 131355 131356 131357 131358 131359 131360 | /* ** Routines used to compute the sum, average, and total. ** ** The SUM() function follows the (broken) SQL standard which means ** that it returns NULL if it sums over no inputs. TOTAL returns ** 0.0 in that case. In addition, TOTAL always returns a float where ** SUM might return an integer if it never encounters a floating point | | | 132336 132337 132338 132339 132340 132341 132342 132343 132344 132345 132346 132347 132348 132349 132350 | /* ** Routines used to compute the sum, average, and total. ** ** The SUM() function follows the (broken) SQL standard which means ** that it returns NULL if it sums over no inputs. TOTAL returns ** 0.0 in that case. In addition, TOTAL always returns a float where ** SUM might return an integer if it never encounters a floating point ** value. TOTAL never fails, but SUM might throw an exception if ** it overflows an integer. */ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ SumCtx *p; int type; assert( argc==1 ); UNUSED_PARAMETER(argc); |
︙ | ︙ | |||
132274 132275 132276 132277 132278 132279 132280 132281 132282 132283 132284 132285 132286 132287 132288 | INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), VFUNCTION(random, 0, 0, 0, randomFunc ), VFUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), FUNCTION(quote, 1, 0, 0, quoteFunc ), VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), VFUNCTION(changes, 0, 0, 0, changes ), VFUNCTION(total_changes, 0, 0, 0, total_changes ), FUNCTION(replace, 3, 0, 0, replaceFunc ), FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), | > > | 133256 133257 133258 133259 133260 133261 133262 133263 133264 133265 133266 133267 133268 133269 133270 133271 133272 | INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), VFUNCTION(random, 0, 0, 0, randomFunc ), VFUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ), DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ), FUNCTION(unistr, 1, 0, 0, unistrFunc ), FUNCTION(quote, 1, 0, 0, quoteFunc ), FUNCTION(unistr_quote, 1, 1, 0, quoteFunc ), VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), VFUNCTION(changes, 0, 0, 0, changes ), VFUNCTION(total_changes, 0, 0, 0, total_changes ), FUNCTION(replace, 3, 0, 0, replaceFunc ), FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), |
︙ | ︙ | |||
134561 134562 134563 134564 134565 134566 134567 | sqlite3MultiValuesEnd(pParse, pLeft); f = SF_Values; }else if( pLeft->pPrior ){ /* In this case set the SF_MultiValue flag only if it was set on pLeft */ f = (f & pLeft->selFlags); } pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); | | | 135545 135546 135547 135548 135549 135550 135551 135552 135553 135554 135555 135556 135557 135558 135559 | sqlite3MultiValuesEnd(pParse, pLeft); f = SF_Values; }else if( pLeft->pPrior ){ /* In this case set the SF_MultiValue flag only if it was set on pLeft */ f = (f & pLeft->selFlags); } pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0); pLeft->selFlags &= ~(u32)SF_MultiValue; if( pSelect ){ pSelect->op = TK_ALL; pSelect->pPrior = pLeft; pLeft = pSelect; } }else{ SrcItem *p = 0; /* SrcItem that reads from co-routine */ |
︙ | ︙ | |||
135981 135982 135983 135984 135985 135986 135987 | ** ** OE_Fail and OE_Ignore must happen before any changes are made. ** OE_Update guarantees that only a single row will change, so it ** must happen before OE_Replace. Technically, OE_Abort and OE_Rollback ** could happen in any order, but they are grouped up front for ** convenience. ** | | | 136965 136966 136967 136968 136969 136970 136971 136972 136973 136974 136975 136976 136977 136978 136979 | ** ** OE_Fail and OE_Ignore must happen before any changes are made. ** OE_Update guarantees that only a single row will change, so it ** must happen before OE_Replace. Technically, OE_Abort and OE_Rollback ** could happen in any order, but they are grouped up front for ** convenience. ** ** 2018-08-14: Ticket https://sqlite.org/src/info/908f001483982c43 ** The order of constraints used to have OE_Update as (2) and OE_Abort ** and so forth as (1). But apparently PostgreSQL checks the OE_Update ** constraint before any others, so it had to be moved. ** ** Constraint checking code is generated in this order: ** (A) The rowid constraint ** (B) Unique index constraints that do not have OE_Replace as their |
︙ | ︙ | |||
139167 139168 139169 139170 139171 139172 139173 | /* 9 */ "name", /* 10 */ "type", /* 11 */ "notnull", /* 12 */ "dflt_value", /* 13 */ "pk", /* 14 */ "hidden", /* table_info reuses 8 */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | > | 140151 140152 140153 140154 140155 140156 140157 140158 140159 140160 140161 140162 140163 140164 140165 140166 140167 140168 140169 140170 140171 140172 140173 140174 140175 140176 140177 140178 140179 140180 140181 140182 140183 140184 140185 140186 140187 140188 140189 140190 140191 140192 140193 140194 140195 140196 140197 140198 140199 140200 140201 140202 140203 140204 140205 140206 | /* 9 */ "name", /* 10 */ "type", /* 11 */ "notnull", /* 12 */ "dflt_value", /* 13 */ "pk", /* 14 */ "hidden", /* table_info reuses 8 */ /* 15 */ "name", /* Used by: function_list */ /* 16 */ "builtin", /* 17 */ "type", /* 18 */ "enc", /* 19 */ "narg", /* 20 */ "flags", /* 21 */ "schema", /* Used by: table_list */ /* 22 */ "name", /* 23 */ "type", /* 24 */ "ncol", /* 25 */ "wr", /* 26 */ "strict", /* 27 */ "seqno", /* Used by: index_xinfo */ /* 28 */ "cid", /* 29 */ "name", /* 30 */ "desc", /* 31 */ "coll", /* 32 */ "key", /* 33 */ "seq", /* Used by: index_list */ /* 34 */ "name", /* 35 */ "unique", /* 36 */ "origin", /* 37 */ "partial", /* 38 */ "tbl", /* Used by: stats */ /* 39 */ "idx", /* 40 */ "wdth", /* 41 */ "hght", /* 42 */ "flgs", /* 43 */ "table", /* Used by: foreign_key_check */ /* 44 */ "rowid", /* 45 */ "parent", /* 46 */ "fkid", /* 47 */ "busy", /* Used by: wal_checkpoint */ /* 48 */ "log", /* 49 */ "checkpointed", /* 50 */ "seq", /* Used by: database_list */ /* 51 */ "name", /* 52 */ "file", /* index_info reuses 27 */ /* 53 */ "database", /* Used by: lock_status */ /* 54 */ "status", /* collation_list reuses 33 */ /* 55 */ "cache_size", /* Used by: default_cache_size */ /* module_list pragma_list reuses 9 */ /* 56 */ "timeout", /* Used by: busy_timeout */ }; /* Definitions of all built-in pragmas */ typedef struct PragmaName { |
︙ | ︙ | |||
139301 139302 139303 139304 139305 139306 139307 | /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CkptFullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, | | | 140285 140286 140287 140288 140289 140290 140291 140292 140293 140294 140295 140296 140297 140298 140299 | /* ColNames: */ 0, 0, /* iArg: */ SQLITE_CkptFullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 33, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) {/* zName: */ "compile_options", /* ePragTyp: */ PragTyp_COMPILE_OPTIONS, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
139336 139337 139338 139339 139340 139341 139342 | /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_Result0, | | | 140320 140321 140322 140323 140324 140325 140326 140327 140328 140329 140330 140331 140332 140333 140334 | /* ColNames: */ 0, 0, /* iArg: */ BTREE_DATA_VERSION }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 50, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 55, 1, |
︙ | ︙ | |||
139416 139417 139418 139419 139420 139421 139422 | /* iArg: */ SQLITE_FullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, | | | 140400 140401 140402 140403 140404 140405 140406 140407 140408 140409 140410 140411 140412 140413 140414 | /* iArg: */ SQLITE_FullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 15, 6, /* iArg: */ 0 }, #endif #endif {/* zName: */ "hard_heap_limit", /* ePragTyp: */ PragTyp_HARD_HEAP_LIMIT, /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
139445 139446 139447 139448 139449 139450 139451 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, | | | | | 140429 140430 140431 140432 140433 140434 140435 140436 140437 140438 140439 140440 140441 140442 140443 140444 140445 140446 140447 140448 140449 140450 140451 140452 140453 | /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 27, 3, /* iArg: */ 0 }, {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 33, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 27, 6, /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) {/* zName: */ "integrity_check", /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
139634 139635 139636 139637 139638 139639 139640 | /* iArg: */ SQLITE_SqlTrace }, #endif #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, | | | | 140618 140619 140620 140621 140622 140623 140624 140625 140626 140627 140628 140629 140630 140631 140632 140633 140634 140635 140636 140637 140638 140639 140640 140641 140642 140643 140644 140645 140646 140647 140648 140649 140650 140651 | /* iArg: */ SQLITE_SqlTrace }, #endif #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG) {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, /* ColNames: */ 38, 5, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "synchronous", /* ePragTyp: */ PragTyp_SYNCHRONOUS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) {/* zName: */ "table_info", /* ePragTyp: */ PragTyp_TABLE_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 8, 6, /* iArg: */ 0 }, {/* zName: */ "table_list", /* ePragTyp: */ PragTyp_TABLE_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1, /* ColNames: */ 21, 6, /* iArg: */ 0 }, {/* zName: */ "table_xinfo", /* ePragTyp: */ PragTyp_TABLE_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 8, 7, /* iArg: */ 1 }, #endif |
︙ | ︙ | |||
139730 139731 139732 139733 139734 139735 139736 | /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, | | | 140714 140715 140716 140717 140718 140719 140720 140721 140722 140723 140724 140725 140726 140727 140728 | /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, /* ColNames: */ 47, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "writable_schema", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, |
︙ | ︙ | |||
139752 139753 139754 139755 139756 139757 139758 | /* ** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands ** will be run with an analysis_limit set to the lessor of the value of ** the following macro or to the actual analysis_limit if it is non-zero, ** in order to prevent PRAGMA optimize from running for too long. ** | | | 140736 140737 140738 140739 140740 140741 140742 140743 140744 140745 140746 140747 140748 140749 140750 | /* ** When the 0x10 bit of PRAGMA optimize is set, any ANALYZE commands ** will be run with an analysis_limit set to the lessor of the value of ** the following macro or to the actual analysis_limit if it is non-zero, ** in order to prevent PRAGMA optimize from running for too long. ** ** The value of 2000 is chosen empirically so that the worst-case run-time ** for PRAGMA optimize does not exceed 100 milliseconds against a variety ** of test databases on a RaspberryPI-4 compiled using -Os and without ** -DSQLITE_DEBUG. Of course, your mileage may vary. For the purpose of ** this paragraph, "worst-case" means that ANALYZE ends up being ** run on every table in the database. The worst case typically only ** happens if PRAGMA optimize is run on a database file for which ANALYZE ** has not been previously run and the 0x10000 flag is included so that |
︙ | ︙ | |||
144041 144042 144043 144044 144045 144046 144047 | pNew->selFlags = selFlags; pNew->iLimit = 0; pNew->iOffset = 0; pNew->selId = ++pParse->nSelect; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; | | | 145025 145026 145027 145028 145029 145030 145031 145032 145033 145034 145035 145036 145037 145038 145039 | pNew->selFlags = selFlags; pNew->iLimit = 0; pNew->iOffset = 0; pNew->selId = ++pParse->nSelect; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; pNew->pHaving = pHaving; pNew->pOrderBy = pOrderBy; pNew->pPrior = 0; pNew->pNext = 0; |
︙ | ︙ | |||
145424 145425 145426 145427 145428 145429 145430 | } /* ** Allocate a KeyInfo object sufficient for an index of N key columns and ** X extra columns. */ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ | | | | | 146408 146409 146410 146411 146412 146413 146414 146415 146416 146417 146418 146419 146420 146421 146422 146423 146424 146425 146426 146427 146428 146429 146430 146431 | } /* ** Allocate a KeyInfo object sufficient for an index of N key columns and ** X extra columns. */ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ int nExtra = (N+X)*(sizeof(CollSeq*)+1); KeyInfo *p = sqlite3DbMallocRawNN(db, SZ_KEYINFO(0) + nExtra); if( p ){ p->aSortFlags = (u8*)&p->aColl[N+X]; p->nKeyField = (u16)N; p->nAllField = (u16)(N+X); p->enc = ENC(db); p->db = db; p->nRef = 1; memset(p->aColl, 0, nExtra); }else{ return (KeyInfo*)sqlite3OomFault(db); } return p; } /* |
︙ | ︙ | |||
147134 147135 147136 147137 147138 147139 147140 147141 147142 147143 147144 147145 147146 147147 | } sqlite3KeyInfoUnref(pKeyInfo); } multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; if( pDelete ){ sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); } return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ | > | 148118 148119 148120 148121 148122 148123 148124 148125 148126 148127 148128 148129 148130 148131 148132 | } sqlite3KeyInfoUnref(pKeyInfo); } multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; pDest->iSDParm2 = dest.iSDParm2; if( pDelete ){ sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); } return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ |
︙ | ︙ | |||
148744 148745 148746 148747 148748 148749 148750 | assert( pE2->op==TK_COLUMN ); if( pE2->iTable==pColumn->iTable && pE2->iColumn==pColumn->iColumn ){ return; /* Already present. Return without doing anything. */ } } | > | | 149729 149730 149731 149732 149733 149734 149735 149736 149737 149738 149739 149740 149741 149742 149743 149744 | assert( pE2->op==TK_COLUMN ); if( pE2->iTable==pColumn->iTable && pE2->iColumn==pColumn->iColumn ){ return; /* Already present. Return without doing anything. */ } } assert( SQLITE_AFF_NONE<SQLITE_AFF_BLOB ); if( sqlite3ExprAffinity(pColumn)<=SQLITE_AFF_BLOB ){ pConst->bHasAffBlob = 1; } pConst->nConst++; pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, pConst->nConst*2*sizeof(Expr*)); if( pConst->apExpr==0 ){ |
︙ | ︙ | |||
148819 148820 148821 148822 148823 148824 148825 | return WRC_Continue; } for(i=0; i<pConst->nConst; i++){ Expr *pColumn = pConst->apExpr[i*2]; if( pColumn==pExpr ) continue; if( pColumn->iTable!=pExpr->iTable ) continue; if( pColumn->iColumn!=pExpr->iColumn ) continue; | > | | 149805 149806 149807 149808 149809 149810 149811 149812 149813 149814 149815 149816 149817 149818 149819 149820 | return WRC_Continue; } for(i=0; i<pConst->nConst; i++){ Expr *pColumn = pConst->apExpr[i*2]; if( pColumn==pExpr ) continue; if( pColumn->iTable!=pExpr->iTable ) continue; if( pColumn->iColumn!=pExpr->iColumn ) continue; assert( SQLITE_AFF_NONE<SQLITE_AFF_BLOB ); if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)<=SQLITE_AFF_BLOB ){ break; } /* A match is found. Add the EP_FixedCol property */ pConst->nChng++; ExprClearProperty(pExpr, EP_Leaf); ExprSetProperty(pExpr, EP_FixedCol); assert( pExpr->pLeft==0 ); |
︙ | ︙ | |||
149472 149473 149474 149475 149476 149477 149478 | ** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) ** ORDER BY ... COLLATE ... ** ** This transformation is necessary because the multiSelectOrderBy() routine ** above that generates the code for a compound SELECT with an ORDER BY clause ** uses a merge algorithm that requires the same collating sequence on the ** result columns as on the ORDER BY clause. See ticket | | | 150459 150460 150461 150462 150463 150464 150465 150466 150467 150468 150469 150470 150471 150472 150473 | ** SELECT * FROM (SELECT ... FROM t1 EXCEPT SELECT ... FROM t2) ** ORDER BY ... COLLATE ... ** ** This transformation is necessary because the multiSelectOrderBy() routine ** above that generates the code for a compound SELECT with an ORDER BY clause ** uses a merge algorithm that requires the same collating sequence on the ** result columns as on the ORDER BY clause. See ticket ** http://sqlite.org/src/info/6709574d2a ** ** This transformation is only needed for EXCEPT, INTERSECT, and UNION. ** The UNION ALL operator works fine with multiSelectOrderBy() even when ** there are COLLATE terms in the ORDER BY. */ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ int i; |
︙ | ︙ | |||
149533 149534 149535 149536 149537 149538 149539 | pNew->pOrderBy = 0; p->pPrior = 0; p->pNext = 0; p->pWith = 0; #ifndef SQLITE_OMIT_WINDOWFUNC p->pWinDefn = 0; #endif | | | 150520 150521 150522 150523 150524 150525 150526 150527 150528 150529 150530 150531 150532 150533 150534 | pNew->pOrderBy = 0; p->pPrior = 0; p->pNext = 0; p->pWith = 0; #ifndef SQLITE_OMIT_WINDOWFUNC p->pWinDefn = 0; #endif p->selFlags &= ~(u32)SF_Compound; assert( (p->selFlags & SF_Converted)==0 ); p->selFlags |= SF_Converted; assert( pNew->pPrior!=0 ); pNew->pPrior->pNext = pNew; pNew->pLimit = 0; return WRC_Continue; } |
︙ | ︙ | |||
149949 149950 149951 149952 149953 149954 149955 | /* Renumber selId because it has been copied from a view */ p->selId = ++pParse->nSelect; } pTabList = p->pSrc; pEList = p->pEList; if( pParse->pWith && (p->selFlags & SF_View) ){ if( p->pWith==0 ){ | | | 150936 150937 150938 150939 150940 150941 150942 150943 150944 150945 150946 150947 150948 150949 150950 | /* Renumber selId because it has been copied from a view */ p->selId = ++pParse->nSelect; } pTabList = p->pSrc; pEList = p->pEList; if( pParse->pWith && (p->selFlags & SF_View) ){ if( p->pWith==0 ){ p->pWith = (With*)sqlite3DbMallocZero(db, SZ_WITH(1) ); if( p->pWith==0 ){ return WRC_Abort; } } p->pWith->bView = 1; } sqlite3WithPush(pParse, p->pWith, 0); |
︙ | ︙ | |||
151088 151089 151090 151091 151092 151093 151094 151095 151096 151097 151098 151099 151100 151101 | ** The transformation only works if all of the following are true: ** ** * The subquery is a UNION ALL of two or more terms ** * The subquery does not have a LIMIT clause ** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries ** * The outer query is a simple count(*) with no WHERE clause or other ** extraneous syntax. ** ** Return TRUE if the optimization is undertaken. */ static int countOfViewOptimization(Parse *pParse, Select *p){ Select *pSub, *pPrior; Expr *pExpr; Expr *pCount; | > | 152075 152076 152077 152078 152079 152080 152081 152082 152083 152084 152085 152086 152087 152088 152089 | ** The transformation only works if all of the following are true: ** ** * The subquery is a UNION ALL of two or more terms ** * The subquery does not have a LIMIT clause ** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries ** * The outer query is a simple count(*) with no WHERE clause or other ** extraneous syntax. ** * None of the subqueries are DISTINCT (forumpost/a860f5fb2e 2025-03-10) ** ** Return TRUE if the optimization is undertaken. */ static int countOfViewOptimization(Parse *pParse, Select *p){ Select *pSub, *pPrior; Expr *pExpr; Expr *pCount; |
︙ | ︙ | |||
151120 151121 151122 151123 151124 151125 151126 | pSub = pFrom->u4.pSubq->pSelect; if( pSub->pPrior==0 ) return 0; /* Must be a compound */ if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ do{ if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ if( pSub->pWhere ) return 0; /* No WHERE clause */ if( pSub->pLimit ) return 0; /* No LIMIT clause */ | > | > > > | | | | 152108 152109 152110 152111 152112 152113 152114 152115 152116 152117 152118 152119 152120 152121 152122 152123 152124 152125 152126 152127 152128 152129 152130 152131 152132 152133 152134 152135 152136 152137 152138 152139 152140 152141 152142 152143 152144 152145 152146 152147 152148 152149 152150 152151 152152 152153 152154 152155 152156 152157 152158 152159 152160 | pSub = pFrom->u4.pSubq->pSelect; if( pSub->pPrior==0 ) return 0; /* Must be a compound */ if( pSub->selFlags & SF_CopyCte ) return 0; /* Not a CTE */ do{ if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ if( pSub->pWhere ) return 0; /* No WHERE clause */ if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & (SF_Aggregate|SF_Distinct) ){ testcase( pSub->selFlags & SF_Aggregate ); testcase( pSub->selFlags & SF_Distinct ); return 0; /* Not an aggregate nor DISTINCT */ } assert( pSub->pHaving==0 ); /* Due to the previous */ pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); /* If we reach this point then it is OK to perform the transformation */ db = pParse->db; pCount = pExpr; pExpr = 0; pSub = sqlite3SubqueryDetach(db, pFrom); sqlite3SrcListDelete(db, p->pSrc); p->pSrc = sqlite3DbMallocZero(pParse->db, SZ_SRCLIST_1); while( pSub ){ Expr *pTerm; pPrior = pSub->pPrior; pSub->pPrior = 0; pSub->pNext = 0; pSub->selFlags |= SF_Aggregate; pSub->selFlags &= ~(u32)SF_Compound; pSub->nSelectRow = 0; sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); sqlite3PExprAddSelect(pParse, pTerm, pSub); if( pExpr==0 ){ pExpr = pTerm; }else{ pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr); } pSub = pPrior; } p->pEList->a[0].pExpr = pExpr; p->selFlags &= ~(u32)SF_Aggregate; #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x200 ){ TREETRACE(0x200,pParse,p,("After count-of-view optimization:\n")); sqlite3TreeViewSelect(0, p, 0); } #endif |
︙ | ︙ | |||
151361 151362 151363 151364 151365 151366 151367 | } #endif sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, p->pOrderBy); testcase( pParse->earlyCleanup ); p->pOrderBy = 0; } | | | 152353 152354 152355 152356 152357 152358 152359 152360 152361 152362 152363 152364 152365 152366 152367 | } #endif sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, p->pOrderBy); testcase( pParse->earlyCleanup ); p->pOrderBy = 0; } p->selFlags &= ~(u32)SF_Distinct; p->selFlags |= SF_NoopOrderBy; } sqlite3SelectPrep(pParse, p, 0); if( pParse->nErr ){ goto select_end; } assert( db->mallocFailed==0 ); |
︙ | ︙ | |||
151400 151401 151402 151403 151404 151405 151406 | goto select_end; } /* Clear the SF_UFSrcCheck flag. The check has already been performed, ** and leaving this flag set can cause errors if a compound sub-query ** in p->pSrc is flattened into this query and this function called ** again as part of compound SELECT processing. */ | | | 152392 152393 152394 152395 152396 152397 152398 152399 152400 152401 152402 152403 152404 152405 152406 | goto select_end; } /* Clear the SF_UFSrcCheck flag. The check has already been performed, ** and leaving this flag set can cause errors if a compound sub-query ** in p->pSrc is flattened into this query and this function called ** again as part of compound SELECT processing. */ p->selFlags &= ~(u32)SF_UFSrcCheck; } if( pDest->eDest==SRT_Output ){ sqlite3GenerateColumnNames(pParse, p); } #ifndef SQLITE_OMIT_WINDOWFUNC |
︙ | ︙ | |||
151889 151890 151891 151892 151893 151894 151895 | if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 && OptimizationEnabled(db, SQLITE_GroupByOrder) #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 #endif ){ | | | 152881 152882 152883 152884 152885 152886 152887 152888 152889 152890 152891 152892 152893 152894 152895 | if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 && OptimizationEnabled(db, SQLITE_GroupByOrder) #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 #endif ){ p->selFlags &= ~(u32)SF_Distinct; pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); if( pGroupBy ){ for(i=0; i<pGroupBy->nExpr; i++){ pGroupBy->a[i].u.x.iOrderByCol = i+1; } } p->selFlags |= SF_Aggregate; |
︙ | ︙ | |||
151998 151999 152000 152001 152002 152003 152004 152005 152006 152007 152008 152009 152010 152011 | /* Begin the database scan. */ TREETRACE(0x2,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, p->pEList, p, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); } if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); } if( sSort.pOrderBy ){ sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); | > > > > > > | 152990 152991 152992 152993 152994 152995 152996 152997 152998 152999 153000 153001 153002 153003 153004 153005 153006 153007 153008 153009 | /* Begin the database scan. */ TREETRACE(0x2,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, p->pEList, p, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); if( pDest->eDest<=SRT_DistQueue && pDest->eDest>=SRT_DistFifo ){ /* TUNING: For a UNION CTE, because UNION is implies DISTINCT, ** reduce the estimated output row count by 8 (LogEst 30). ** Search for tag-20250414a to see other cases */ p->nSelectRow -= 30; } } if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); } if( sSort.pOrderBy ){ sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); |
︙ | ︙ | |||
153923 153924 153925 153926 153927 153928 153929 | int regIn /* The first in an array of registers */ ){ Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; ExprList *pNew; Returning *pReturning; Select sSelect; | | > > | | | | | | | 154921 154922 154923 154924 154925 154926 154927 154928 154929 154930 154931 154932 154933 154934 154935 154936 154937 154938 154939 154940 154941 154942 154943 154944 154945 154946 154947 154948 154949 154950 154951 154952 154953 154954 154955 154956 154957 154958 154959 | int regIn /* The first in an array of registers */ ){ Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; ExprList *pNew; Returning *pReturning; Select sSelect; SrcList *pFrom; u8 fromSpace[SZ_SRCLIST_1]; assert( v!=0 ); if( !pParse->bReturning ){ /* This RETURNING trigger must be for a different statement as ** this statement lacks a RETURNING clause. */ return; } assert( db->pParse==pParse ); assert( !pParse->isCreate ); pReturning = pParse->u1.d.pReturning; if( pTrigger != &(pReturning->retTrig) ){ /* This RETURNING trigger is for a different statement */ return; } memset(&sSelect, 0, sizeof(sSelect)); pFrom = (SrcList*)fromSpace; memset(pFrom, 0, SZ_SRCLIST_1); sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); sSelect.pSrc = pFrom; pFrom->nSrc = 1; pFrom->a[0].pSTab = pTab; pFrom->a[0].zName = pTab->zName; /* tag-20240424-1 */ pFrom->a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); if( pParse->nErr==0 ){ assert( db->mallocFailed==0 ); sqlite3GenerateColumnNames(pParse, &sSelect); } sqlite3ExprListDelete(db, sSelect.pEList); pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); |
︙ | ︙ | |||
156267 156268 156269 156270 156271 156272 156273 | /* Default behavior: Report an error if the argument to VACUUM is ** not recognized */ iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm); if( iDb<0 ) goto build_vacuum_end; #else /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments ** to VACUUM are silently ignored. This is a back-out of a bug fix that | | | 157267 157268 157269 157270 157271 157272 157273 157274 157275 157276 157277 157278 157279 157280 157281 | /* Default behavior: Report an error if the argument to VACUUM is ** not recognized */ iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm); if( iDb<0 ) goto build_vacuum_end; #else /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments ** to VACUUM are silently ignored. This is a back-out of a bug fix that ** occurred on 2016-08-19 (https://sqlite.org/src/info/083f9e6270). ** The buggy behavior is required for binary compatibility with some ** legacy applications. */ iDb = sqlite3FindDb(pParse->db, pNm); if( iDb<0 ) iDb = 0; #endif } if( iDb!=1 ){ |
︙ | ︙ | |||
156346 156347 156348 156349 156350 156351 156352 | ** restored before returning. Then set the writable-schema flag, and ** disable CHECK and foreign key constraints. */ saved_flags = db->flags; saved_mDbFlags = db->mDbFlags; saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; saved_mTrace = db->mTrace; | | | 157346 157347 157348 157349 157350 157351 157352 157353 157354 157355 157356 157357 157358 157359 157360 | ** restored before returning. Then set the writable-schema flag, and ** disable CHECK and foreign key constraints. */ saved_flags = db->flags; saved_mDbFlags = db->mDbFlags; saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; saved_mTrace = db->mTrace; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows); db->mTrace = 0; zDbMain = db->aDb[iDb].zDbSName; pMain = db->aDb[iDb].pBt; |
︙ | ︙ | |||
158475 158476 158477 158478 158479 158480 158481 | int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ | | > > > > > | 159475 159476 159477 159478 159479 159480 159481 159482 159483 159484 159485 159486 159487 159488 159489 159490 159491 159492 159493 159494 159495 159496 | int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ WhereLevel a[FLEXARRAY]; /* Information about each nest loop in WHERE */ }; /* ** The size (in bytes) of a WhereInfo object that holds N WhereLevels. */ #define SZ_WHEREINFO(N) ROUND8(offsetof(WhereInfo,a)+(N)*sizeof(WhereLevel)) /* ** Private interfaces - callable only by other where.c routines. ** ** where.c: */ SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); #ifdef WHERETRACE_ENABLED |
︙ | ︙ | |||
159157 159158 159159 159160 159161 159162 159163 | } } /* ** pX is an expression of the form: (vector) IN (SELECT ...) ** In other words, it is a vector IN operator with a SELECT clause on the | | | 160162 160163 160164 160165 160166 160167 160168 160169 160170 160171 160172 160173 160174 160175 160176 | } } /* ** pX is an expression of the form: (vector) IN (SELECT ...) ** In other words, it is a vector IN operator with a SELECT clause on the ** RHS. But not all terms in the vector are indexable and the terms might ** not be in the correct order for indexing. ** ** This routine makes a copy of the input pX expression and then adjusts ** the vector on the LHS with corresponding changes to the SELECT so that ** the vector contains only index terms and those terms are in the correct ** order. The modified IN expression is returned. The caller is responsible ** for deleting the returned expression. |
︙ | ︙ | |||
160928 160929 160930 160931 160932 160933 160934 | ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; | | < | 161933 161934 161935 161936 161937 161938 161939 161940 161941 161942 161943 161944 161945 161946 161947 | ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; pOrTab = sqlite3DbMallocRawNN(db, SZ_SRCLIST(nNotReady+1)); if( pOrTab==0 ) return notReady; pOrTab->nAlloc = (u8)(nNotReady + 1); pOrTab->nSrc = pOrTab->nAlloc; memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem)); origSrc = pWInfo->pTabList->a; for(k=1; k<=nNotReady; k++){ memcpy(&pOrTab->a[k], &origSrc[pLevel[k].iFrom], sizeof(pOrTab->a[k])); |
︙ | ︙ | |||
160980 160981 160982 160983 160984 160985 160986 | ** Actually, each subexpression is converted to "xN AND w" where w is ** the "interesting" terms of z - terms that did not originate in the ** ON or USING clause of a LEFT JOIN, and terms that are usable as ** indices. ** ** This optimization also only applies if the (x1 OR x2 OR ...) term ** is not contained in the ON clause of a LEFT JOIN. | | | 161984 161985 161986 161987 161988 161989 161990 161991 161992 161993 161994 161995 161996 161997 161998 | ** Actually, each subexpression is converted to "xN AND w" where w is ** the "interesting" terms of z - terms that did not originate in the ** ON or USING clause of a LEFT JOIN, and terms that are usable as ** indices. ** ** This optimization also only applies if the (x1 OR x2 OR ...) term ** is not contained in the ON clause of a LEFT JOIN. ** See ticket http://sqlite.org/src/info/f2369304e4 ** ** 2022-02-04: Do not push down slices of a row-value comparison. ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, ** the initialization of the right-hand operand of the vector comparison ** might not occur, or might occur only in an OR branch that is not ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. ** |
︙ | ︙ | |||
161472 161473 161474 161475 161476 161477 161478 | Vdbe *v = pParse->pVdbe; WhereRightJoin *pRJ = pLevel->pRJ; Expr *pSubWhere = 0; WhereClause *pWC = &pWInfo->sWC; WhereInfo *pSubWInfo; WhereLoop *pLoop = pLevel->pWLoop; SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; | | > | 162476 162477 162478 162479 162480 162481 162482 162483 162484 162485 162486 162487 162488 162489 162490 162491 | Vdbe *v = pParse->pVdbe; WhereRightJoin *pRJ = pLevel->pRJ; Expr *pSubWhere = 0; WhereClause *pWC = &pWInfo->sWC; WhereInfo *pSubWInfo; WhereLoop *pLoop = pLevel->pWLoop; SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; SrcList *pFrom; u8 fromSpace[SZ_SRCLIST_1]; Bitmask mAll = 0; int k; ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pSTab->zName)); sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, pRJ->regReturn); for(k=0; k<iLevel; k++){ |
︙ | ︙ | |||
161516 161517 161518 161519 161520 161521 161522 | } if( pTerm->prereqAll & ~mAll ) continue; if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue; pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); } } | > | | | | | | 162521 162522 162523 162524 162525 162526 162527 162528 162529 162530 162531 162532 162533 162534 162535 162536 162537 162538 162539 162540 162541 162542 | } if( pTerm->prereqAll & ~mAll ) continue; if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue; pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); } } pFrom = (SrcList*)fromSpace; pFrom->nSrc = 1; pFrom->nAlloc = 1; memcpy(&pFrom->a[0], pTabItem, sizeof(SrcItem)); pFrom->a[0].fg.jointype = 0; assert( pParse->withinRJSubrtn < 100 ); pParse->withinRJSubrtn++; pSubWInfo = sqlite3WhereBegin(pParse, pFrom, pSubWhere, 0, 0, 0, WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ int iCur = pLevel->iTabCur; int r = ++pParse->nMem; int nPk; int jmp; int addrCont = sqlite3WhereContinueLabel(pSubWInfo); |
︙ | ︙ | |||
163510 163511 163512 163513 163514 163515 163516 | typedef struct HiddenIndexInfo HiddenIndexInfo; struct HiddenIndexInfo { WhereClause *pWC; /* The Where clause being analyzed */ Parse *pParse; /* The parsing context */ int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ u32 mIn; /* Mask of terms that are <col> IN (...) */ u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */ | | | | > > > > > | 164516 164517 164518 164519 164520 164521 164522 164523 164524 164525 164526 164527 164528 164529 164530 164531 164532 164533 164534 164535 164536 164537 164538 164539 | typedef struct HiddenIndexInfo HiddenIndexInfo; struct HiddenIndexInfo { WhereClause *pWC; /* The Where clause being analyzed */ Parse *pParse; /* The parsing context */ int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ u32 mIn; /* Mask of terms that are <col> IN (...) */ u32 mHandleIn; /* Terms that vtab will handle as <col> IN (...) */ sqlite3_value *aRhs[FLEXARRAY]; /* RHS values for constraints. MUST BE LAST ** Extra space is allocated to hold up ** to nTerm such values */ }; /* Size (in bytes) of a HiddenIndeInfo object sufficient to hold as ** many as N constraints */ #define SZ_HIDDENINDEXINFO(N) \ (offsetof(HiddenIndexInfo,aRhs) + (N)*sizeof(sqlite3_value*)) /* Forward declaration of methods */ static int whereLoopResize(sqlite3*, WhereLoop*, int); /* ** Return the estimated number of output rows from a WHERE clause */ SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ |
︙ | ︙ | |||
164579 164580 164581 164582 164583 164584 164585 164586 164587 164588 164589 164590 164591 164592 | if( extraCols & MASKBIT(i) ) nKeyCol++; } if( pSrc->colUsed & MASKBIT(BMS-1) ){ nKeyCol += pTable->nCol - BMS + 1; } /* Construct the Index object to describe this index */ pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+HasRowid(pTable), 0, &zNotUsed); if( pIdx==0 ) goto end_auto_index_create; pLoop->u.btree.pIndex = pIdx; pIdx->zName = "auto-index"; pIdx->pTable = pTable; n = 0; | > > | 165590 165591 165592 165593 165594 165595 165596 165597 165598 165599 165600 165601 165602 165603 165604 165605 | if( extraCols & MASKBIT(i) ) nKeyCol++; } if( pSrc->colUsed & MASKBIT(BMS-1) ){ nKeyCol += pTable->nCol - BMS + 1; } /* Construct the Index object to describe this index */ assert( nKeyCol <= pTable->nCol + MAX(0, pTable->nCol - BMS + 1) ); /* ^-- This guarantees that the number of index columns will fit in the u16 */ pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+HasRowid(pTable), 0, &zNotUsed); if( pIdx==0 ) goto end_auto_index_create; pLoop->u.btree.pIndex = pIdx; pIdx->zName = "auto-index"; pIdx->pTable = pTable; n = 0; |
︙ | ︙ | |||
164990 164991 164992 164993 164994 164995 164996 | } } /* Allocate the sqlite3_index_info structure */ pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm | | | | 166003 166004 166005 166006 166007 166008 166009 166010 166011 166012 166013 166014 166015 166016 166017 166018 | } } /* Allocate the sqlite3_index_info structure */ pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + sizeof(*pIdxOrderBy)*nOrderBy + SZ_HIDDENINDEXINFO(nTerm) ); if( pIdxInfo==0 ){ sqlite3ErrorMsg(pParse, "out of memory"); return 0; } pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; |
︙ | ︙ | |||
166944 166945 166946 166947 166948 166949 166950 | }else{ pNew->nOut = nOutUnadjusted; } if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEq<pProbe->nColumn && (pNew->u.btree.nEq<pProbe->nKeyCol || | | | 167957 167958 167959 167960 167961 167962 167963 167964 167965 167966 167967 167968 167969 167970 167971 | }else{ pNew->nOut = nOutUnadjusted; } if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEq<pProbe->nColumn && (pNew->u.btree.nEq<pProbe->nKeyCol || (pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY && !pProbe->bIdxRowid)) ){ if( pNew->u.btree.nEq>3 ){ sqlite3ProgressCheck(pParse); } whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); } pNew->nOut = saved_nOut; |
︙ | ︙ | |||
170185 170186 170187 170188 170189 170190 170191 | /* Allocate and initialize the WhereInfo structure that will become the ** return value. A single allocation is used to store the WhereInfo ** struct, the contents of WhereInfo.a[], the WhereClause structure ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte ** field (type Bitmask) it must be aligned on an 8-byte boundary on ** some architectures. Hence the ROUND8() below. */ | | < < < | 171198 171199 171200 171201 171202 171203 171204 171205 171206 171207 171208 171209 171210 171211 171212 | /* Allocate and initialize the WhereInfo structure that will become the ** return value. A single allocation is used to store the WhereInfo ** struct, the contents of WhereInfo.a[], the WhereClause structure ** and the WhereMaskSet structure. Since WhereClause contains an 8-byte ** field (type Bitmask) it must be aligned on an 8-byte boundary on ** some architectures. Hence the ROUND8() below. */ nByteWInfo = SZ_WHEREINFO(nTabList); pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); pWInfo = 0; goto whereBeginError; } pWInfo->pParse = pParse; |
︙ | ︙ | |||
170405 170406 170407 170408 170409 170410 170411 | if( pWInfo->pOrderBy ){ whereInterstageHeuristic(pWInfo); wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } /* TUNING: Assume that a DISTINCT clause on a subquery reduces | | > | 171415 171416 171417 171418 171419 171420 171421 171422 171423 171424 171425 171426 171427 171428 171429 171430 | if( pWInfo->pOrderBy ){ whereInterstageHeuristic(pWInfo); wherePathSolver(pWInfo, pWInfo->nRowOut<0 ? 1 : pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } /* TUNING: Assume that a DISTINCT clause on a subquery reduces ** the output size by a factor of 8 (LogEst -30). Search for ** tag-20250414a to see other cases. */ if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", pWInfo->nRowOut, pWInfo->nRowOut-30)); pWInfo->nRowOut -= 30; } |
︙ | ︙ | |||
172140 172141 172142 172143 172144 172145 172146 | sqlite3WalkExprList(&w, p->pOrderBy); } p->pSrc = 0; p->pWhere = 0; p->pGroupBy = 0; p->pHaving = 0; | | | 173151 173152 173153 173154 173155 173156 173157 173158 173159 173160 173161 173162 173163 173164 173165 | sqlite3WalkExprList(&w, p->pOrderBy); } p->pSrc = 0; p->pWhere = 0; p->pGroupBy = 0; p->pHaving = 0; p->selFlags &= ~(u32)SF_Aggregate; p->selFlags |= SF_WinRewrite; /* Create the ORDER BY clause for the sub-select. This is the concatenation ** of the window PARTITION and ORDER BY clauses. Then, if this makes it ** redundant, remove the ORDER BY from the parent SELECT. */ pSort = exprListAppendList(pParse, 0, pMWin->pPartition, 1); pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1); |
︙ | ︙ | |||
178279 178280 178281 178282 178283 178284 178285 | parserDoubleLinkSelect(pParse, pRhs); pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0); pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)yymsp[-1].minor.yy502; pRhs->pPrior = pLhs; | | | | 179290 179291 179292 179293 179294 179295 179296 179297 179298 179299 179300 179301 179302 179303 179304 179305 | parserDoubleLinkSelect(pParse, pRhs); pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0); pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)yymsp[-1].minor.yy502; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~(u32)SF_MultiValue; pRhs->selFlags &= ~(u32)SF_MultiValue; if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } yymsp[-2].minor.yy637 = pRhs; } break; |
︙ | ︙ | |||
181024 181025 181026 181027 181028 181029 181030 | }else if( tokenType==TK_OVER ){ assert( n==4 ); tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); }else if( tokenType==TK_FILTER ){ assert( n==6 ); tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ | | > > > > | 182035 182036 182037 182038 182039 182040 182041 182042 182043 182044 182045 182046 182047 182048 182049 182050 182051 182052 182053 | }else if( tokenType==TK_OVER ){ assert( n==4 ); tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); }else if( tokenType==TK_FILTER ){ assert( n==6 ); tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ }else if( tokenType==TK_COMMENT && (db->init.busy || (db->flags & SQLITE_Comments)!=0) ){ /* Ignore SQL comments if either (1) we are reparsing the schema or ** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */ zSql += n; continue; }else if( tokenType!=TK_QNUMBER ){ Token x; x.z = zSql; x.n = n; sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x); |
︙ | ︙ | |||
181919 181920 181921 181922 181923 181924 181925 181926 181927 181928 181929 181930 181931 181932 | if( rc==SQLITE_OK ){ rc = sqlite3MemdbInit(); } #endif if( rc==SQLITE_OK ){ sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); sqlite3MemoryBarrier(); sqlite3GlobalConfig.isInit = 1; #ifdef SQLITE_EXTRA_INIT bRunExtraInit = 1; #endif } sqlite3GlobalConfig.inProgress = 0; | > > > > > > > > | 182934 182935 182936 182937 182938 182939 182940 182941 182942 182943 182944 182945 182946 182947 182948 182949 182950 182951 182952 182953 182954 182955 | if( rc==SQLITE_OK ){ rc = sqlite3MemdbInit(); } #endif if( rc==SQLITE_OK ){ sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); #ifdef SQLITE_EXTRA_INIT_MUTEXED { int SQLITE_EXTRA_INIT_MUTEXED(const char*); rc = SQLITE_EXTRA_INIT_MUTEXED(0); } #endif } if( rc==SQLITE_OK ){ sqlite3MemoryBarrier(); sqlite3GlobalConfig.isInit = 1; #ifdef SQLITE_EXTRA_INIT bRunExtraInit = 1; #endif } sqlite3GlobalConfig.inProgress = 0; |
︙ | ︙ | |||
183395 183396 183397 183398 183399 183400 183401 183402 183403 183404 183405 183406 183407 183408 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); db->busyHandler.xBusyHandler = xBusy; db->busyHandler.pBusyArg = pArg; db->busyHandler.nBusy = 0; db->busyTimeout = 0; sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* ** This routine sets the progress callback for an Sqlite database to the | > > > | 184418 184419 184420 184421 184422 184423 184424 184425 184426 184427 184428 184429 184430 184431 184432 184433 184434 | if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif sqlite3_mutex_enter(db->mutex); db->busyHandler.xBusyHandler = xBusy; db->busyHandler.pBusyArg = pArg; db->busyHandler.nBusy = 0; db->busyTimeout = 0; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT db->setlkTimeout = 0; #endif sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* ** This routine sets the progress callback for an Sqlite database to the |
︙ | ︙ | |||
183444 183445 183446 183447 183448 183449 183450 183451 183452 183453 183454 183455 183456 183457 183458 183459 183460 183461 183462 | #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif if( ms>0 ){ sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, (void*)db); db->busyTimeout = ms; }else{ sqlite3_busy_handler(db, 0, 0); } return SQLITE_OK; } /* ** Cause any pending operation to stop at its earliest opportunity. */ SQLITE_API void sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 184470 184471 184472 184473 184474 184475 184476 184477 184478 184479 184480 184481 184482 184483 184484 184485 184486 184487 184488 184489 184490 184491 184492 184493 184494 184495 184496 184497 184498 184499 184500 184501 184502 184503 184504 184505 184506 184507 184508 184509 184510 184511 184512 184513 184514 184515 184516 184517 184518 184519 184520 184521 184522 184523 | #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif if( ms>0 ){ sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, (void*)db); db->busyTimeout = ms; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT db->setlkTimeout = ms; #endif }else{ sqlite3_busy_handler(db, 0, 0); } return SQLITE_OK; } /* ** Set the setlk timeout value. */ SQLITE_API int sqlite3_setlk_timeout(sqlite3 *db, int ms, int flags){ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT int iDb; int bBOC = ((flags & SQLITE_SETLK_BLOCK_ON_CONNECT) ? 1 : 0); #endif #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif if( ms<-1 ) return SQLITE_RANGE; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT db->setlkTimeout = ms; db->setlkFlags = flags; sqlite3BtreeEnterAll(db); for(iDb=0; iDb<db->nDb; iDb++){ Btree *pBt = db->aDb[iDb].pBt; if( pBt ){ sqlite3_file *fd = sqlite3PagerFile(sqlite3BtreePager(pBt)); sqlite3OsFileControlHint(fd, SQLITE_FCNTL_BLOCK_ON_CONNECT, (void*)&bBOC); } } sqlite3BtreeLeaveAll(db); #endif #if !defined(SQLITE_ENABLE_API_ARMOR) && !defined(SQLITE_ENABLE_SETLK_TIMEOUT) UNUSED_PARAMETER(db); UNUSED_PARAMETER(flags); #endif return SQLITE_OK; } /* ** Cause any pending operation to stop at its earliest opportunity. */ SQLITE_API void sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) |
︙ | ︙ | |||
185415 185416 185417 185418 185419 185420 185421 | return SQLITE_OK; } }else if( pData==0 ){ sqlite3_mutex_leave(db->mutex); return SQLITE_OK; }else{ size_t n = strlen(zName); | | | 186476 186477 186478 186479 186480 186481 186482 186483 186484 186485 186486 186487 186488 186489 186490 | return SQLITE_OK; } }else if( pData==0 ){ sqlite3_mutex_leave(db->mutex); return SQLITE_OK; }else{ size_t n = strlen(zName); p = sqlite3_malloc64( SZ_DBCLIENTDATA(n+1) ); if( p==0 ){ if( xDestructor ) xDestructor(pData); sqlite3_mutex_leave(db->mutex); return SQLITE_NOMEM; } memcpy(p->zName, zName, n+1); p->pNext = db->pDbData; |
︙ | ︙ | |||
185781 185782 185783 185784 185785 185786 185787 | break; } #endif /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); ** ** If b is true, then activate the SQLITE_FkNoAction setting. If b is | | | | 186842 186843 186844 186845 186846 186847 186848 186849 186850 186851 186852 186853 186854 186855 186856 186857 | break; } #endif /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); ** ** If b is true, then activate the SQLITE_FkNoAction setting. If b is ** false then clear that setting. If the SQLITE_FkNoAction setting is ** enabled, all foreign key ON DELETE and ON UPDATE actions behave as if ** they were NO ACTION, regardless of how they are defined. ** ** NB: One must usually run "PRAGMA writable_schema=RESET" after ** using this test-control, before it will take full effect. failing ** to reset the schema can result in some unexpected behavior. */ case SQLITE_TESTCTRL_FK_NO_ACTION: { |
︙ | ︙ | |||
187129 187130 187131 187132 187133 187134 187135 | ** } ** varint POS_END; (marks end of positions for this document. ** } ** ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream ** generated by the tokenizer. Note that POS_END and POS_COLUMN occur | | | 188190 188191 188192 188193 188194 188195 188196 188197 188198 188199 188200 188201 188202 188203 188204 | ** } ** varint POS_END; (marks end of positions for this document. ** } ** ** Here, array { X } means zero or more occurrences of X, adjacent in ** memory. A "position" is an index of a token in the token stream ** generated by the tokenizer. Note that POS_END and POS_COLUMN occur ** in the same logical place as the position element, and act as sentinels ** ending a position list array. POS_END is 0. POS_COLUMN is 1. ** The positions numbers are not stored literally but rather as two more ** than the difference from the prior position, or the just the position plus ** 2 for the first position. Example: ** ** label: A B C D E F G H I J K ** value: 123 5 9 1 1 14 35 0 234 72 0 |
︙ | ︙ | |||
187347 187348 187349 187350 187351 187352 187353 187354 187355 187356 187357 187358 187359 187360 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** */ #ifndef _FTSINT_H #define _FTSINT_H #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif /* FTS3/FTS4 require virtual tables */ #ifdef SQLITE_OMIT_VIRTUALTABLE | > > > > > > > | 188408 188409 188410 188411 188412 188413 188414 188415 188416 188417 188418 188419 188420 188421 188422 188423 188424 188425 188426 188427 188428 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** */ #ifndef _FTSINT_H #define _FTSINT_H /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stddef.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* #include <stdarg.h> */ #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif /* FTS3/FTS4 require virtual tables */ #ifdef SQLITE_OMIT_VIRTUALTABLE |
︙ | ︙ | |||
187816 187817 187818 187819 187820 187821 187822 187823 187824 187825 187826 187827 187828 187829 | # define TESTONLY(X) #endif #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) #define deliberate_fall_through #endif /* SQLITE_AMALGAMATION */ #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); # define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() #else | > > > > > > > > > > > > > | 188884 188885 188886 188887 188888 188889 188890 188891 188892 188893 188894 188895 188896 188897 188898 188899 188900 188901 188902 188903 188904 188905 188906 188907 188908 188909 188910 | # define TESTONLY(X) #endif #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) #define deliberate_fall_through /* ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof # define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY #else # define FLEXARRAY 1 #endif #endif /* SQLITE_AMALGAMATION */ #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); # define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() #else |
︙ | ︙ | |||
187921 187922 187923 187924 187925 187926 187927 | ** verifying the operation of the SQLite core. */ int inTransaction; /* True after xBegin but before xCommit/xRollback */ int mxSavepoint; /* Largest valid xSavepoint integer */ #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) | | | 189002 189003 189004 189005 189006 189007 189008 189009 189010 189011 189012 189013 189014 189015 189016 | ** verifying the operation of the SQLite core. */ int inTransaction; /* True after xBegin but before xCommit/xRollback */ int mxSavepoint; /* Largest valid xSavepoint integer */ #endif #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* True to disable the incremental doclist optimization. This is controlled ** by special insert command 'test-no-incr-doclist'. */ int bNoIncrDoclist; /* Number of segments in a level */ int nMergeCount; #endif }; |
︙ | ︙ | |||
187973 187974 187975 187976 187977 187978 187979 | #define FTS3_EVAL_FILTER 0 #define FTS3_EVAL_NEXT 1 #define FTS3_EVAL_MATCHINFO 2 /* ** The Fts3Cursor.eSearch member is always set to one of the following. | | | 189054 189055 189056 189057 189058 189059 189060 189061 189062 189063 189064 189065 189066 189067 189068 | #define FTS3_EVAL_FILTER 0 #define FTS3_EVAL_NEXT 1 #define FTS3_EVAL_MATCHINFO 2 /* ** The Fts3Cursor.eSearch member is always set to one of the following. ** Actually, Fts3Cursor.eSearch can be greater than or equal to ** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index ** of the column to be searched. For example, in ** ** CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d); ** SELECT docid FROM ex1 WHERE b MATCH 'one two three'; ** ** Because the LHS of the MATCH operator is 2nd column "b", |
︙ | ︙ | |||
188046 188047 188048 188049 188050 188051 188052 | i64 iOrDocid; /* Variables below this point are populated by fts3_expr.c when parsing ** a MATCH expression. Everything above is part of the evaluation phase. */ int nToken; /* Number of tokens in the phrase */ int iColumn; /* Index of column this phrase must match */ | | > > > > | 189127 189128 189129 189130 189131 189132 189133 189134 189135 189136 189137 189138 189139 189140 189141 189142 189143 189144 189145 189146 | i64 iOrDocid; /* Variables below this point are populated by fts3_expr.c when parsing ** a MATCH expression. Everything above is part of the evaluation phase. */ int nToken; /* Number of tokens in the phrase */ int iColumn; /* Index of column this phrase must match */ Fts3PhraseToken aToken[FLEXARRAY]; /* One for each token in the phrase */ }; /* Size (in bytes) of an Fts3Phrase object large enough to hold N tokens */ #define SZ_FTS3PHRASE(N) \ (offsetof(Fts3Phrase,aToken)+(N)*sizeof(Fts3PhraseToken)) /* ** A tree of these objects forms the RHS of a MATCH operator. ** ** If Fts3Expr.eType is FTSQUERY_PHRASE and isLoaded is true, then aDoclist ** points to a malloced buffer, size nDoclist bytes, containing the results ** of this phrase query in FTS3 doclist format. As usual, the initial |
︙ | ︙ | |||
188282 188283 188284 188285 188286 188287 188288 | /************** Continuing where we left off in fts3.c ***********************/ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) # define SQLITE_CORE 1 #endif | < < < < < < | 189367 189368 189369 189370 189371 189372 189373 189374 189375 189376 189377 189378 189379 189380 | /************** Continuing where we left off in fts3.c ***********************/ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_CORE) # define SQLITE_CORE 1 #endif /* #include "fts3.h" */ #ifndef SQLITE_CORE /* # include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #endif |
︙ | ︙ | |||
190626 190627 190628 190629 190630 190631 190632 | ** be larger in the output than it was in the input (since the delta value ** may be a larger positive integer than the actual docid). ** ** The space required to store the output is therefore the sum of the ** sizes of the two inputs, plus enough space for exactly one of the input ** docids to grow. ** | | | 191705 191706 191707 191708 191709 191710 191711 191712 191713 191714 191715 191716 191717 191718 191719 | ** be larger in the output than it was in the input (since the delta value ** may be a larger positive integer than the actual docid). ** ** The space required to store the output is therefore the sum of the ** sizes of the two inputs, plus enough space for exactly one of the input ** docids to grow. ** ** A symmetric argument may be made if the doclists are in descending ** order. */ aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); if( !aOut ) return SQLITE_NOMEM; p = aOut; fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); |
︙ | ︙ | |||
192724 192725 192726 192727 192728 192729 192730 | /* ** The phrase iterator passed as the second argument: ** ** * features at least one token that uses an incremental doclist, and ** ** * does not contain any deferred tokens. ** | | | 193803 193804 193805 193806 193807 193808 193809 193810 193811 193812 193813 193814 193815 193816 193817 | /* ** The phrase iterator passed as the second argument: ** ** * features at least one token that uses an incremental doclist, and ** ** * does not contain any deferred tokens. ** ** Advance it to the next matching document in the database and populate ** the Fts3Doclist.pList and nList fields. ** ** If there is no "next" entry and no error occurs, then *pbEof is set to ** 1 before returning. Otherwise, if no error occurs and the iterator is ** successfully advanced, *pbEof is set to 0. ** ** If an error occurs, return an SQLite error code. Otherwise, return |
︙ | ︙ | |||
193731 193732 193733 193734 193735 193736 193737 | pCsr->isEof = 1; } return rc; } /* | | | 194810 194811 194812 194813 194814 194815 194816 194817 194818 194819 194820 194821 194822 194823 194824 | pCsr->isEof = 1; } return rc; } /* ** Restart iteration for expression pExpr so that the next call to ** fts3EvalNext() visits the first row. Do not allow incremental ** loading or merging of phrase doclists for this iteration. ** ** If *pRc is other than SQLITE_OK when this function is called, it is ** a no-op. If an error occurs within this function, *pRc is set to an ** SQLite error code before returning. */ |
︙ | ︙ | |||
194922 194923 194924 194925 194926 194927 194928 194929 194930 194931 194932 194933 194934 194935 | } /* ** Function getNextNode(), which is called by fts3ExprParse(), may itself ** call fts3ExprParse(). So this forward declaration is required. */ static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); /* ** Extract the next token from buffer z (length n) using the tokenizer ** and other information (column names etc.) in pParse. Create an Fts3Expr ** structure of type FTSQUERY_PHRASE containing a phrase consisting of this ** single token and set *ppExpr to point to it. If the end of the buffer is ** reached before a token is found, set *ppExpr to zero. It is the | > > > > > > > > > > > > > > > > > | 196001 196002 196003 196004 196005 196006 196007 196008 196009 196010 196011 196012 196013 196014 196015 196016 196017 196018 196019 196020 196021 196022 196023 196024 196025 196026 196027 196028 196029 196030 196031 | } /* ** Function getNextNode(), which is called by fts3ExprParse(), may itself ** call fts3ExprParse(). So this forward declaration is required. */ static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); /* ** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis ** is defined, search for '(' and ')' as well. Return the index of the first ** such character in the buffer. If there is no such character, return -1. */ static int findBarredChar(const char *z, int n){ int ii; for(ii=0; ii<n; ii++){ if( (z[ii]=='"') || (sqlite3_fts3_enable_parentheses && (z[ii]=='(' || z[ii]==')')) ){ return ii; } } return -1; } /* ** Extract the next token from buffer z (length n) using the tokenizer ** and other information (column names etc.) in pParse. Create an Fts3Expr ** structure of type FTSQUERY_PHRASE containing a phrase consisting of this ** single token and set *ppExpr to point to it. If the end of the buffer is ** reached before a token is found, set *ppExpr to zero. It is the |
︙ | ︙ | |||
194947 194948 194949 194950 194951 194952 194953 | int *pnConsumed /* OUT: Number of bytes consumed */ ){ sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; int rc; sqlite3_tokenizer_cursor *pCursor; Fts3Expr *pRet = 0; | < < < < < < < | | > > > > > > > > > > > | | | 196043 196044 196045 196046 196047 196048 196049 196050 196051 196052 196053 196054 196055 196056 196057 196058 196059 196060 196061 196062 196063 196064 196065 196066 196067 196068 196069 196070 196071 196072 196073 196074 196075 196076 196077 196078 196079 196080 196081 196082 196083 196084 196085 196086 196087 196088 | int *pnConsumed /* OUT: Number of bytes consumed */ ){ sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; int rc; sqlite3_tokenizer_cursor *pCursor; Fts3Expr *pRet = 0; *pnConsumed = n; rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor); if( rc==SQLITE_OK ){ const char *zToken; int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; sqlite3_int64 nByte; /* total space to allocate */ rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); if( rc==SQLITE_OK ){ /* Check that this tokenization did not gobble up any " characters. Or, ** if enable_parenthesis is true, that it did not gobble up any ** open or close parenthesis characters either. If it did, call ** getNextToken() again, but pass only that part of the input buffer ** up to the first such character. */ int iBarred = findBarredChar(z, iEnd); if( iBarred>=0 ){ pModule->xClose(pCursor); return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed); } nByte = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1) + nToken; pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); if( !pRet ){ rc = SQLITE_NOMEM; }else{ pRet->eType = FTSQUERY_PHRASE; pRet->pPhrase = (Fts3Phrase *)&pRet[1]; pRet->pPhrase->nToken = 1; pRet->pPhrase->iColumn = iCol; pRet->pPhrase->aToken[0].n = nToken; pRet->pPhrase->aToken[0].z = (char*)&pRet->pPhrase->aToken[1]; memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken); if( iEnd<n && z[iEnd]=='*' ){ pRet->pPhrase->aToken[0].isPrefix = 1; iEnd++; } |
︙ | ︙ | |||
194998 194999 195000 195001 195002 195003 195004 | }else{ break; } } } *pnConsumed = iEnd; | | > > > > | 196098 196099 196100 196101 196102 196103 196104 196105 196106 196107 196108 196109 196110 196111 196112 196113 196114 196115 196116 | }else{ break; } } } *pnConsumed = iEnd; }else if( n && rc==SQLITE_DONE ){ int iBarred = findBarredChar(z, n); if( iBarred>=0 ){ *pnConsumed = iBarred; } rc = SQLITE_OK; } pModule->xClose(pCursor); } *ppExpr = pRet; |
︙ | ︙ | |||
195047 195048 195049 195050 195051 195052 195053 | sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; int rc; Fts3Expr *p = 0; sqlite3_tokenizer_cursor *pCursor = 0; char *zTemp = 0; i64 nTemp = 0; | | | 196151 196152 196153 196154 196155 196156 196157 196158 196159 196160 196161 196162 196163 196164 196165 | sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; int rc; Fts3Expr *p = 0; sqlite3_tokenizer_cursor *pCursor = 0; char *zTemp = 0; i64 nTemp = 0; const int nSpace = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1); int nToken = 0; /* The final Fts3Expr data structure, including the Fts3Phrase, ** Fts3PhraseToken structures token buffers are all stored as a single ** allocation so that the expression can be freed with a single call to ** sqlite3_free(). Setting this up requires a two pass approach. ** |
︙ | ︙ | |||
195419 195420 195421 195422 195423 195424 195425 | p = pPrev; }else{ int eType = p->eType; isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); /* The isRequirePhrase variable is set to true if a phrase or ** an expression contained in parenthesis is required. If a | | | 196523 196524 196525 196526 196527 196528 196529 196530 196531 196532 196533 196534 196535 196536 196537 | p = pPrev; }else{ int eType = p->eType; isPhrase = (eType==FTSQUERY_PHRASE || p->pLeft); /* The isRequirePhrase variable is set to true if a phrase or ** an expression contained in parenthesis is required. If a ** binary operator (AND, OR, NOT or NEAR) is encountered when ** isRequirePhrase is set, this is a syntax error. */ if( !isPhrase && isRequirePhrase ){ sqlite3Fts3ExprFree(p); rc = SQLITE_ERROR; goto exprparse_out; } |
︙ | ︙ | |||
196001 196002 196003 196004 196005 196006 196007 | }else{ rc = fts3ExprParseUnbalanced( pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr ); } if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ | < | 197105 197106 197107 197108 197109 197110 197111 197112 197113 197114 197115 197116 197117 197118 | }else{ rc = fts3ExprParseUnbalanced( pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr ); } if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ sqlite3_result_error(context, "Error parsing expression", -1); }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ sqlite3_result_error_nomem(context); }else{ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); sqlite3_free(zBuf); } |
︙ | ︙ | |||
196244 196245 196246 196247 196248 196249 196250 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } | | | 197347 197348 197349 197350 197351 197352 197353 197354 197355 197356 197357 197358 197359 197360 197361 | pH->first = pNew; } pEntry->count++; pEntry->chain = pNew; } /* Resize the hash table so that it contains "new_size" buckets. ** "new_size" must be a power of 2. The hash table might fail ** to resize if sqliteMalloc() fails. ** ** Return non-zero if a memory allocation error occurs. */ static int fts3Rehash(Fts3Hash *pH, int new_size){ struct _fts3ht *new_ht; /* The new hash table */ |
︙ | ︙ | |||
196699 196700 196701 196702 196703 196704 196705 | z[0]!='w' && z[0]!='x' && z[0]!='y' && isVowel(z+1) && isConsonant(z+2); } /* ** If the word ends with zFrom and xCond() is true for the stem | | | 197802 197803 197804 197805 197806 197807 197808 197809 197810 197811 197812 197813 197814 197815 197816 | z[0]!='w' && z[0]!='x' && z[0]!='y' && isVowel(z+1) && isConsonant(z+2); } /* ** If the word ends with zFrom and xCond() is true for the stem ** of the word that precedes the zFrom ending, then change the ** ending to zTo. ** ** The input word *pz and zFrom are both in reverse order. zTo ** is in normal order. ** ** Return TRUE if zFrom matches. Return FALSE if zFrom does not ** match. Not that TRUE is returned even if xCond() fails and |
︙ | ︙ | |||
198210 198211 198212 198213 198214 198215 198216 | Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(nVal); fts3tokResetCursor(pCsr); if( idxNum==1 ){ const char *zByte = (const char *)sqlite3_value_text(apVal[0]); | | | 199313 199314 199315 199316 199317 199318 199319 199320 199321 199322 199323 199324 199325 199326 199327 | Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(nVal); fts3tokResetCursor(pCsr); if( idxNum==1 ){ const char *zByte = (const char *)sqlite3_value_text(apVal[0]); sqlite3_int64 nByte = sqlite3_value_bytes(apVal[0]); pCsr->zInput = sqlite3_malloc64(nByte+1); if( pCsr->zInput==0 ){ rc = SQLITE_NOMEM; }else{ if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte); pCsr->zInput[nByte] = 0; rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr); |
︙ | ︙ | |||
202282 202283 202284 202285 202286 202287 202288 | ** If the size of the value in blob pPrev is zero, then this is the first ** term written to the node. Otherwise, pPrev contains a copy of the ** previous term. Before this function returns, it is updated to contain a ** copy of zTerm/nTerm. ** ** It is assumed that the buffer associated with pNode is already large ** enough to accommodate the new entry. The buffer associated with pPrev | | | 203385 203386 203387 203388 203389 203390 203391 203392 203393 203394 203395 203396 203397 203398 203399 | ** If the size of the value in blob pPrev is zero, then this is the first ** term written to the node. Otherwise, pPrev contains a copy of the ** previous term. Before this function returns, it is updated to contain a ** copy of zTerm/nTerm. ** ** It is assumed that the buffer associated with pNode is already large ** enough to accommodate the new entry. The buffer associated with pPrev ** is extended by this function if required. ** ** If an error (i.e. OOM condition) occurs, an SQLite error code is ** returned. Otherwise, SQLITE_OK. */ static int fts3AppendToNode( Blob *pNode, /* Current node image to append to */ Blob *pPrev, /* Buffer containing previous term written */ |
︙ | ︙ | |||
203945 203946 203947 203948 203949 203950 203951 | return SQLITE_OK; } #endif /* ** SQLite value pRowid contains the rowid of a row that may or may not be ** present in the FTS3 table. If it is, delete it and adjust the contents | | | 205048 205049 205050 205051 205052 205053 205054 205055 205056 205057 205058 205059 205060 205061 205062 | return SQLITE_OK; } #endif /* ** SQLite value pRowid contains the rowid of a row that may or may not be ** present in the FTS3 table. If it is, delete it and adjust the contents ** of subsidiary data structures accordingly. */ static int fts3DeleteByRowid( Fts3Table *p, sqlite3_value *pRowid, int *pnChng, /* IN/OUT: Decrement if row is deleted */ u32 *aSzDel ){ |
︙ | ︙ | |||
204271 204272 204273 204274 204275 204276 204277 | ** for details. */ struct MatchinfoBuffer { u8 aRef[3]; int nElem; int bGlobal; /* Set if global data is loaded */ char *zMatchinfo; | | > > > > | 205374 205375 205376 205377 205378 205379 205380 205381 205382 205383 205384 205385 205386 205387 205388 205389 205390 205391 205392 205393 | ** for details. */ struct MatchinfoBuffer { u8 aRef[3]; int nElem; int bGlobal; /* Set if global data is loaded */ char *zMatchinfo; u32 aMI[FLEXARRAY]; }; /* Size (in bytes) of a MatchinfoBuffer sufficient for N elements */ #define SZ_MATCHINFOBUFFER(N) \ (offsetof(MatchinfoBuffer,aMI)+(((N)+1)/2)*sizeof(u64)) /* ** The snippet() and offsets() functions both return text values. An instance ** of the following structure is used to accumulate those values while the ** functions are running. See fts3StringAppend() for details. */ |
︙ | ︙ | |||
204298 204299 204300 204301 204302 204303 204304 | /* ** Allocate a two-slot MatchinfoBuffer object. */ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ MatchinfoBuffer *pRet; sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) | | | | | | | | | | | | 205405 205406 205407 205408 205409 205410 205411 205412 205413 205414 205415 205416 205417 205418 205419 205420 205421 205422 205423 205424 205425 205426 205427 205428 205429 205430 205431 205432 205433 205434 205435 205436 205437 205438 205439 205440 205441 205442 205443 205444 205445 205446 205447 205448 205449 205450 205451 205452 205453 205454 205455 205456 205457 205458 205459 205460 205461 205462 205463 205464 205465 205466 205467 205468 205469 205470 205471 205472 205473 205474 205475 205476 205477 205478 205479 205480 | /* ** Allocate a two-slot MatchinfoBuffer object. */ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ MatchinfoBuffer *pRet; sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) + SZ_MATCHINFOBUFFER(1); sqlite3_int64 nStr = strlen(zMatchinfo); pRet = sqlite3Fts3MallocZero(nByte + nStr+1); if( pRet ){ pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet; pRet->aMI[1+nElem] = pRet->aMI[0] + sizeof(u32)*((int)nElem+1); pRet->nElem = (int)nElem; pRet->zMatchinfo = ((char*)pRet) + nByte; memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1); pRet->aRef[0] = 1; } return pRet; } static void fts3MIBufferFree(void *p){ MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]); assert( (u32*)p==&pBuf->aMI[1] || (u32*)p==&pBuf->aMI[pBuf->nElem+2] ); if( (u32*)p==&pBuf->aMI[1] ){ pBuf->aRef[1] = 0; }else{ pBuf->aRef[2] = 0; } if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){ sqlite3_free(pBuf); } } static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ void (*xRet)(void*) = 0; u32 *aOut = 0; if( p->aRef[1]==0 ){ p->aRef[1] = 1; aOut = &p->aMI[1]; xRet = fts3MIBufferFree; } else if( p->aRef[2]==0 ){ p->aRef[2] = 1; aOut = &p->aMI[p->nElem+2]; xRet = fts3MIBufferFree; }else{ aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); if( aOut ){ xRet = sqlite3_free; if( p->bGlobal ) memcpy(aOut, &p->aMI[1], p->nElem*sizeof(u32)); } } *paOut = aOut; return xRet; } static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ p->bGlobal = 1; memcpy(&p->aMI[2+p->nElem], &p->aMI[1], p->nElem*sizeof(u32)); } /* ** Free a MatchinfoBuffer object allocated using fts3MIBufferNew() */ SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){ if( p ){ |
︙ | ︙ | |||
204774 204775 204776 204777 204778 204779 204780 | int nAppend /* Size of zAppend in bytes (or -1) */ ){ if( nAppend<0 ){ nAppend = (int)strlen(zAppend); } /* If there is insufficient space allocated at StrBuffer.z, use realloc() | | | 205881 205882 205883 205884 205885 205886 205887 205888 205889 205890 205891 205892 205893 205894 205895 | int nAppend /* Size of zAppend in bytes (or -1) */ ){ if( nAppend<0 ){ nAppend = (int)strlen(zAppend); } /* If there is insufficient space allocated at StrBuffer.z, use realloc() ** to grow the buffer until so that it is big enough to accommodate the ** appended data. */ if( pStr->n+nAppend+1>=pStr->nAlloc ){ sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; char *zNew = sqlite3_realloc64(pStr->z, nAlloc); if( !zNew ){ return SQLITE_NOMEM; |
︙ | ︙ | |||
205186 205187 205188 205189 205190 205191 205192 | case FTS3_MATCHINFO_AVGLENGTH: case FTS3_MATCHINFO_LENGTH: case FTS3_MATCHINFO_LCS: nVal = pInfo->nCol; break; case FTS3_MATCHINFO_LHITS: | | | | | 206293 206294 206295 206296 206297 206298 206299 206300 206301 206302 206303 206304 206305 206306 206307 206308 206309 206310 206311 206312 206313 206314 206315 206316 | case FTS3_MATCHINFO_AVGLENGTH: case FTS3_MATCHINFO_LENGTH: case FTS3_MATCHINFO_LCS: nVal = pInfo->nCol; break; case FTS3_MATCHINFO_LHITS: nVal = (size_t)pInfo->nCol * pInfo->nPhrase; break; case FTS3_MATCHINFO_LHITS_BM: nVal = (size_t)pInfo->nPhrase * ((pInfo->nCol + 31) / 32); break; default: assert( cArg==FTS3_MATCHINFO_HITS ); nVal = (size_t)pInfo->nCol * pInfo->nPhrase * 3; break; } return nVal; } static int fts3MatchinfoSelectDoctotal( |
︙ | ︙ | |||
206753 206754 206755 206756 206757 206758 206759 | ** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). ** All generated JSON text still conforms strictly to RFC-8259, but text ** with JSON-5 extensions is accepted as input. ** ** Beginning with version 3.45.0 (circa 2024-01-01), these routines also ** accept BLOB values that have JSON encoded using a binary representation ** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk | | | | 207860 207861 207862 207863 207864 207865 207866 207867 207868 207869 207870 207871 207872 207873 207874 207875 | ** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). ** All generated JSON text still conforms strictly to RFC-8259, but text ** with JSON-5 extensions is accepted as input. ** ** Beginning with version 3.45.0 (circa 2024-01-01), these routines also ** accept BLOB values that have JSON encoded using a binary representation ** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk ** format for SQLite-JSONB is completely different and incompatible with ** PostgreSQL-JSONB. ** ** Decoding and interpreting JSONB is still O(N) where N is the size of ** the input, the same as text JSON. However, the constant of proportionality ** for JSONB is much smaller due to faster parsing. The size of each ** element in JSONB is encoded in its header, so there is no need to search ** for delimiters using persnickety syntax rules. JSONB seems to be about ** 3x faster than text JSON as a result. JSONB is also tends to be slightly |
︙ | ︙ | |||
206811 206812 206813 206814 206815 206816 206817 | ** 12 1 byte (0-255) 2 ** 13 2 byte (0-65535) 3 ** 14 4 byte (0-4294967295) 5 ** 15 8 byte (0-1.8e19) 9 ** ** The payload size need not be expressed in its minimal form. For example, ** if the payload size is 10, the size can be expressed in any of 5 different | | | | 207918 207919 207920 207921 207922 207923 207924 207925 207926 207927 207928 207929 207930 207931 207932 207933 207934 207935 207936 207937 207938 207939 207940 207941 207942 | ** 12 1 byte (0-255) 2 ** 13 2 byte (0-65535) 3 ** 14 4 byte (0-4294967295) 5 ** 15 8 byte (0-1.8e19) 9 ** ** The payload size need not be expressed in its minimal form. For example, ** if the payload size is 10, the size can be expressed in any of 5 different ** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by one 0x0a byte, ** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by ** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and ** a single byte of 0x0a. The shorter forms are preferred, of course, but ** sometimes when generating JSONB, the payload size is not known in advance ** and it is convenient to reserve sufficient header space to cover the ** largest possible payload size and then come back later and patch up ** the size when it becomes known, resulting in a non-minimal encoding. ** ** The value (X>>4)==15 is not actually used in the current implementation ** (as SQLite is currently unable to handle BLOBs larger than about 2GB) ** but is included in the design to allow for future enhancements. ** ** The payload follows the header. NULL, TRUE, and FALSE have no payload and ** their payload size must always be zero. The payload for INT, INT5, ** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the ** "..." or '...' delimiters are omitted from the various text encodings. ** The payload for ARRAY and OBJECT is a list of additional elements that |
︙ | ︙ | |||
206881 206882 206883 206884 206885 206886 206887 | /* ** Growing our own isspace() routine this way is twice as fast as ** the library isspace() function, resulting in a 7% overall performance ** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { | > > | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > | 207988 207989 207990 207991 207992 207993 207994 207995 207996 207997 207998 207999 208000 208001 208002 208003 208004 208005 208006 208007 208008 208009 208010 208011 208012 208013 208014 208015 208016 208017 208018 208019 208020 208021 208022 208023 208024 208025 208026 208027 208028 208029 208030 208031 208032 208033 208034 208035 208036 208037 208038 208039 208040 208041 208042 208043 208044 208045 208046 208047 208048 208049 208050 208051 208052 208053 208054 208055 208056 208057 208058 208059 208060 208061 208062 208063 208064 208065 208066 208067 208068 208069 208070 208071 208072 208073 208074 208075 208076 208077 208078 208079 208080 208081 208082 208083 208084 208085 208086 208087 208088 208089 208090 208091 208092 208093 208094 208095 208096 208097 208098 208099 208100 208101 208102 208103 208104 | /* ** Growing our own isspace() routine this way is twice as fast as ** the library isspace() function, resulting in a 7% overall performance ** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { #ifdef SQLITE_ASCII /*0 1 2 3 4 5 6 7 8 9 a b c d e f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ #endif #ifdef SQLITE_EBCDIC /*0 1 2 3 4 5 6 7 8 9 a b c d e f */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 3 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 6 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f */ #endif }; #define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) /* ** The set of all space characters recognized by jsonIsspace(). ** Useful as the second argument to strspn(). */ #ifdef SQLITE_ASCII static const char jsonSpaces[] = "\011\012\015\040"; #endif #ifdef SQLITE_EBCDIC static const char jsonSpaces[] = "\005\045\015\100"; #endif /* ** Characters that are special to JSON. Control characters, ** '"' and '\\' and '\''. Actually, '\'' is not special to ** canonical JSON, but it is special in JSON-5, so we include ** it in the set of special characters. */ static const char jsonIsOk[256] = { #ifdef SQLITE_ASCII /*0 1 2 3 4 5 6 7 8 9 a b c d e f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 2 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 3 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 5 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ #endif #ifdef SQLITE_EBCDIC /*0 1 2 3 4 5 6 7 8 9 a b c d e f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, /* 3 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 5 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, /* 7 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f */ #endif }; /* Objects */ typedef struct JsonCache JsonCache; typedef struct JsonString JsonString; typedef struct JsonParse JsonParse; |
︙ | ︙ | |||
207075 207076 207077 207078 207079 207080 207081 | #define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ #define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ /************************************************************************** ** Forward references **************************************************************************/ static void jsonReturnStringAsBlob(JsonString*); | | | 208235 208236 208237 208238 208239 208240 208241 208242 208243 208244 208245 208246 208247 208248 208249 | #define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ #define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ /************************************************************************** ** Forward references **************************************************************************/ static void jsonReturnStringAsBlob(JsonString*); static int jsonArgIsJsonb(sqlite3_value *pJson, JsonParse *p); static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); static void jsonReturnParse(sqlite3_context*,JsonParse*); static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); static void jsonParseFree(JsonParse*); static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); static u32 jsonUnescapeOneChar(const char*, u32, u32*); |
︙ | ︙ | |||
207149 207150 207151 207152 207153 207154 207155 | ** Search for a cached translation the json text supplied by pArg. Return ** the JsonParse object if found. Return NULL if not found. ** ** When a match if found, the matching entry is moved to become the ** most-recently used entry if it isn't so already. ** ** The JsonParse object returned still belongs to the Cache and might | | | 208309 208310 208311 208312 208313 208314 208315 208316 208317 208318 208319 208320 208321 208322 208323 | ** Search for a cached translation the json text supplied by pArg. Return ** the JsonParse object if found. Return NULL if not found. ** ** When a match if found, the matching entry is moved to become the ** most-recently used entry if it isn't so already. ** ** The JsonParse object returned still belongs to the Cache and might ** be deleted at any moment. If the caller wants the JsonParse to ** linger, it needs to increment the nPJRef reference counter. */ static JsonParse *jsonCacheSearch( sqlite3_context *ctx, /* The SQL statement context holding the cache */ sqlite3_value *pArg /* Function argument containing SQL text */ ){ JsonCache *p; |
︙ | ︙ | |||
207493 207494 207495 207496 207497 207498 207499 | jsonAppendRaw(p, z, n); }else{ jsonAppendString(p, z, n); } break; } default: { | < | | | < | 208653 208654 208655 208656 208657 208658 208659 208660 208661 208662 208663 208664 208665 208666 208667 208668 208669 | jsonAppendRaw(p, z, n); }else{ jsonAppendString(p, z, n); } break; } default: { JsonParse px; memset(&px, 0, sizeof(px)); if( jsonArgIsJsonb(pValue, &px) ){ jsonTranslateBlobToText(&px, 0, p); }else if( p->eErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); p->eErr = JSTRING_ERR; jsonStringReset(p); } break; |
︙ | ︙ | |||
207895 207896 207897 207898 207899 207900 207901 | const void *aPayload ){ if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; jsonBlobAppendNode(pParse, eType, szPayload, aPayload); } | | | 209053 209054 209055 209056 209057 209058 209059 209060 209061 209062 209063 209064 209065 209066 209067 | const void *aPayload ){ if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; jsonBlobAppendNode(pParse, eType, szPayload, aPayload); } /* Append a node type byte together with the payload size and ** possibly also the payload. ** ** If aPayload is not NULL, then it is a pointer to the payload which ** is also appended. If aPayload is NULL, the pParse->aBlob[] array ** is resized (if necessary) so that it is big enough to hold the ** payload, but the payload is not appended and pParse->nBlob is left ** pointing to where the first byte of payload will eventually be. |
︙ | ︙ | |||
209171 209172 209173 209174 209175 209176 209177 | i = jsonTranslateBlobToText(pParse, i, pOut); break; } } return i; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < | 210329 210330 210331 210332 210333 210334 210335 210336 210337 210338 210339 210340 210341 210342 | i = jsonTranslateBlobToText(pParse, i, pOut); break; } } return i; } /* ** Given that a JSONB_ARRAY object starts at offset i, return ** the number of entries in that array. */ static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ u32 n, sz, i, iEnd; u32 k = 0; |
︙ | ︙ | |||
209229 209230 209231 209232 209233 209234 209235 209236 209237 209238 209239 209240 209241 209242 | nBlob = pParse->nBlob; pParse->nBlob = pParse->nBlobAlloc; (void)jsonbPayloadSize(pParse, iRoot, &sz); pParse->nBlob = nBlob; sz += pParse->delta; pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); } /* ** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of ** content beginning at iDel, and replacing them with nIns bytes of ** content given by aIns. ** ** nDel may be zero, in which case no bytes are removed. But iDel is | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 210360 210361 210362 210363 210364 210365 210366 210367 210368 210369 210370 210371 210372 210373 210374 210375 210376 210377 210378 210379 210380 210381 210382 210383 210384 210385 210386 210387 210388 210389 210390 210391 210392 210393 210394 210395 210396 210397 210398 210399 210400 210401 210402 210403 210404 210405 210406 210407 210408 210409 210410 210411 210412 210413 210414 210415 210416 210417 210418 210419 210420 210421 210422 210423 210424 210425 210426 210427 210428 210429 210430 210431 210432 210433 210434 210435 210436 210437 210438 210439 210440 210441 210442 210443 210444 210445 210446 210447 210448 210449 | nBlob = pParse->nBlob; pParse->nBlob = pParse->nBlobAlloc; (void)jsonbPayloadSize(pParse, iRoot, &sz); pParse->nBlob = nBlob; sz += pParse->delta; pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); } /* ** If the JSONB at aIns[0..nIns-1] can be expanded (by denormalizing the ** size field) by d bytes, then write the expansion into aOut[] and ** return true. In this way, an overwrite happens without changing the ** size of the JSONB, which reduces memcpy() operations and also make it ** faster and easier to update the B-Tree entry that contains the JSONB ** in the database. ** ** If the expansion of aIns[] by d bytes cannot be (easily) accomplished ** then return false. ** ** The d parameter is guaranteed to be between 1 and 8. ** ** This routine is an optimization. A correct answer is obtained if it ** always leaves the output unchanged and returns false. */ static int jsonBlobOverwrite( u8 *aOut, /* Overwrite here */ const u8 *aIns, /* New content */ u32 nIns, /* Bytes of new content */ u32 d /* Need to expand new content by this much */ ){ u32 szPayload; /* Bytes of payload */ u32 i; /* New header size, after expansion & a loop counter */ u8 szHdr; /* Size of header before expansion */ /* Lookup table for finding the upper 4 bits of the first byte of the ** expanded aIns[], based on the size of the expanded aIns[] header: ** ** 2 3 4 5 6 7 8 9 */ static const u8 aType[] = { 0xc0, 0xd0, 0, 0xe0, 0, 0, 0, 0xf0 }; if( (aIns[0]&0x0f)<=2 ) return 0; /* Cannot enlarge NULL, true, false */ switch( aIns[0]>>4 ){ default: { /* aIns[] header size 1 */ if( ((1<<d)&0x116)==0 ) return 0; /* d must be 1, 2, 4, or 8 */ i = d + 1; /* New hdr sz: 2, 3, 5, or 9 */ szHdr = 1; break; } case 12: { /* aIns[] header size is 2 */ if( ((1<<d)&0x8a)==0) return 0; /* d must be 1, 3, or 7 */ i = d + 2; /* New hdr sz: 2, 5, or 9 */ szHdr = 2; break; } case 13: { /* aIns[] header size is 3 */ if( d!=2 && d!=6 ) return 0; /* d must be 2 or 6 */ i = d + 3; /* New hdr sz: 5 or 9 */ szHdr = 3; break; } case 14: { /* aIns[] header size is 5 */ if( d!=4 ) return 0; /* d must be 4 */ i = 9; /* New hdr sz: 9 */ szHdr = 5; break; } case 15: { /* aIns[] header size is 9 */ return 0; /* No solution */ } } assert( i>=2 && i<=9 && aType[i-2]!=0 ); aOut[0] = (aIns[0] & 0x0f) | aType[i-2]; memcpy(&aOut[i], &aIns[szHdr], nIns-szHdr); szPayload = nIns - szHdr; while( 1/*edit-by-break*/ ){ i--; aOut[i] = szPayload & 0xff; if( i==1 ) break; szPayload >>= 8; } assert( (szPayload>>8)==0 ); return 1; } /* ** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of ** content beginning at iDel, and replacing them with nIns bytes of ** content given by aIns. ** ** nDel may be zero, in which case no bytes are removed. But iDel is |
︙ | ︙ | |||
209251 209252 209253 209254 209255 209256 209257 209258 209259 209260 209261 209262 209263 209264 209265 209266 209267 209268 | JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ u32 iDel, /* First byte to be removed */ u32 nDel, /* Number of bytes to remove */ const u8 *aIns, /* Content to insert */ u32 nIns /* Bytes of content to insert */ ){ i64 d = (i64)nIns - (i64)nDel; if( d!=0 ){ if( pParse->nBlob + d > pParse->nBlobAlloc ){ jsonBlobExpand(pParse, pParse->nBlob+d); if( pParse->oom ) return; } memmove(&pParse->aBlob[iDel+nIns], &pParse->aBlob[iDel+nDel], pParse->nBlob - (iDel+nDel)); pParse->nBlob += d; pParse->delta += d; } | > > > > > > | > | 210458 210459 210460 210461 210462 210463 210464 210465 210466 210467 210468 210469 210470 210471 210472 210473 210474 210475 210476 210477 210478 210479 210480 210481 210482 210483 210484 210485 210486 210487 210488 210489 210490 | JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ u32 iDel, /* First byte to be removed */ u32 nDel, /* Number of bytes to remove */ const u8 *aIns, /* Content to insert */ u32 nIns /* Bytes of content to insert */ ){ i64 d = (i64)nIns - (i64)nDel; if( d<0 && d>=(-8) && aIns!=0 && jsonBlobOverwrite(&pParse->aBlob[iDel], aIns, nIns, (int)-d) ){ return; } if( d!=0 ){ if( pParse->nBlob + d > pParse->nBlobAlloc ){ jsonBlobExpand(pParse, pParse->nBlob+d); if( pParse->oom ) return; } memmove(&pParse->aBlob[iDel+nIns], &pParse->aBlob[iDel+nDel], pParse->nBlob - (iDel+nDel)); pParse->nBlob += d; pParse->delta += d; } if( nIns && aIns ){ memcpy(&pParse->aBlob[iDel], aIns, nIns); } } /* ** Return the number of escaped newlines to be ignored. ** An escaped newline is a one of the following byte sequences: ** ** 0x5c 0x0a |
︙ | ︙ | |||
209942 209943 209944 209945 209946 209947 209948 | switch( eType ){ default: { pParse->aBlob = aNull; pParse->nBlob = 1; return 0; } case SQLITE_BLOB: { | < < | < | 211156 211157 211158 211159 211160 211161 211162 211163 211164 211165 211166 211167 211168 211169 211170 | switch( eType ){ default: { pParse->aBlob = aNull; pParse->nBlob = 1; return 0; } case SQLITE_BLOB: { if( !jsonArgIsJsonb(pArg, pParse) ){ sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); return 1; } break; } case SQLITE_TEXT: { const char *zJson = (const char*)sqlite3_value_text(pArg); |
︙ | ︙ | |||
210025 210026 210027 210028 210029 210030 210031 | }else{ sqlite3_result_error_nomem(ctx); } return 0; } /* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent | | | 211236 211237 211238 211239 211240 211241 211242 211243 211244 211245 211246 211247 211248 211249 211250 | }else{ sqlite3_result_error_nomem(ctx); } return 0; } /* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent ** arguments come in pairs where each pair contains a JSON path and ** content to insert or set at that patch. Do the updates ** and return the result. ** ** The specific operation is determined by eEdit, which can be one ** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. */ static void jsonInsertIntoBlob( |
︙ | ︙ | |||
210096 210097 210098 210099 210100 210101 210102 | } return; } /* ** If pArg is a blob that seems like a JSONB blob, then initialize ** p to point to that JSONB and return TRUE. If pArg does not seem like | | | > > > > > | > > > > > > > > > > > > > > | > > | | < < < < < | | > > > | 211307 211308 211309 211310 211311 211312 211313 211314 211315 211316 211317 211318 211319 211320 211321 211322 211323 211324 211325 211326 211327 211328 211329 211330 211331 211332 211333 211334 211335 211336 211337 211338 211339 211340 211341 211342 211343 211344 211345 211346 211347 211348 211349 211350 211351 211352 211353 211354 211355 211356 211357 211358 211359 211360 | } return; } /* ** If pArg is a blob that seems like a JSONB blob, then initialize ** p to point to that JSONB and return TRUE. If pArg does not seem like ** a JSONB blob, then return FALSE. ** ** For small BLOBs (having no more than 7 bytes of payload) a full ** validity check is done. So for small BLOBs this routine only returns ** true if the value is guaranteed to be a valid JSONB. For larger BLOBs ** (8 byte or more of payload) only the size of the outermost element is ** checked to verify that the BLOB is superficially valid JSONB. ** ** A full JSONB validation is done on smaller BLOBs because those BLOBs might ** also be text JSON that has been incorrectly cast into a BLOB. ** (See tag-20240123-a and https://sqlite.org/forum/forumpost/012136abd5) ** If the BLOB is 9 bytes are larger, then it is not possible for the ** superficial size check done here to pass if the input is really text ** JSON so we do not need to look deeper in that case. ** ** Why we only need to do full JSONB validation for smaller BLOBs: ** ** The first byte of valid JSON text must be one of: '{', '[', '"', ' ', '\n', ** '\r', '\t', '-', or a digit '0' through '9'. Of these, only a subset ** can also be the first byte of JSONB: '{', '[', and digits '3' ** through '9'. In every one of those cases, the payload size is 7 bytes ** or less. So if we do full JSONB validation for every BLOB where the ** payload is less than 7 bytes, we will never get a false positive for ** JSONB on an input that is really text JSON. */ static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ u32 n, sz = 0; u8 c; if( sqlite3_value_type(pArg)!=SQLITE_BLOB ) return 0; p->aBlob = (u8*)sqlite3_value_blob(pArg); p->nBlob = (u32)sqlite3_value_bytes(pArg); if( p->nBlob>0 && ALWAYS(p->aBlob!=0) && ((c = p->aBlob[0]) & 0x0f)<=JSONB_OBJECT && (n = jsonbPayloadSize(p, 0, &sz))>0 && sz+n==p->nBlob && ((c & 0x0f)>JSONB_FALSE || sz==0) && (sz>7 || (c!=0x7b && c!=0x5b && !sqlite3Isdigit(c)) || jsonbValidityCheck(p, 0, p->nBlob, 1)==0) ){ return 1; } p->aBlob = 0; p->nBlob = 0; return 0; } |
︙ | ︙ | |||
210194 210195 210196 210197 210198 210199 210200 | /* If the blob is not valid JSONB, fall through into trying to cast ** the blob into text which is then interpreted as JSON. (tag-20240123-a) ** ** This goes against all historical documentation about how the SQLite ** JSON functions were suppose to work. From the beginning, blob was ** reserved for expansion and a blob value should have raised an error. ** But it did not, due to a bug. And many applications came to depend | | | 211424 211425 211426 211427 211428 211429 211430 211431 211432 211433 211434 211435 211436 211437 211438 | /* If the blob is not valid JSONB, fall through into trying to cast ** the blob into text which is then interpreted as JSON. (tag-20240123-a) ** ** This goes against all historical documentation about how the SQLite ** JSON functions were suppose to work. From the beginning, blob was ** reserved for expansion and a blob value should have raised an error. ** But it did not, due to a bug. And many applications came to depend ** upon this buggy behavior, especially when using the CLI and reading ** JSON text using readfile(), which returns a blob. For this reason ** we will continue to support the bug moving forward. ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d */ } p->zJson = (char*)sqlite3_value_text(pArg); p->nJson = sqlite3_value_bytes(pArg); |
︙ | ︙ | |||
211209 211210 211211 211212 211213 211214 211215 | #ifdef SQLITE_LEGACY_JSON_VALID /* Incorrect legacy behavior was to return FALSE for a NULL input */ sqlite3_result_int(ctx, 0); #endif return; } case SQLITE_BLOB: { | > > | | < < < < < | < | 212439 212440 212441 212442 212443 212444 212445 212446 212447 212448 212449 212450 212451 212452 212453 212454 212455 212456 212457 212458 212459 212460 212461 212462 212463 | #ifdef SQLITE_LEGACY_JSON_VALID /* Incorrect legacy behavior was to return FALSE for a NULL input */ sqlite3_result_int(ctx, 0); #endif return; } case SQLITE_BLOB: { JsonParse py; memset(&py, 0, sizeof(py)); if( jsonArgIsJsonb(argv[0], &py) ){ if( flags & 0x04 ){ /* Superficial checking only - accomplished by the ** jsonArgIsJsonb() call above. */ res = 1; }else if( flags & 0x08 ){ /* Strict checking. Check by translating BLOB->TEXT->BLOB. If ** no errors occur, call that a "strict check". */ res = 0==jsonbValidityCheck(&py, 0, py.nBlob, 1); } break; } /* Fall through into interpreting the input as text. See note ** above at tag-20240123-a. */ /* no break */ deliberate_fall_through } |
︙ | ︙ | |||
211281 211282 211283 211284 211285 211286 211287 | i64 iErrPos = 0; /* Error position to be returned */ JsonParse s; assert( argc==1 ); UNUSED_PARAMETER(argc); memset(&s, 0, sizeof(s)); s.db = sqlite3_context_db_handle(ctx); | < | < | 212507 212508 212509 212510 212511 212512 212513 212514 212515 212516 212517 212518 212519 212520 212521 | i64 iErrPos = 0; /* Error position to be returned */ JsonParse s; assert( argc==1 ); UNUSED_PARAMETER(argc); memset(&s, 0, sizeof(s)); s.db = sqlite3_context_db_handle(ctx); if( jsonArgIsJsonb(argv[0], &s) ){ iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); }else{ s.zJson = (char*)sqlite3_value_text(argv[0]); if( s.zJson==0 ) return; /* NULL input or OOM */ s.nJson = sqlite3_value_bytes(argv[0]); if( jsonConvertTextToBlob(&s,0) ){ if( s.oom ){ |
︙ | ︙ | |||
211968 211969 211970 211971 211972 211973 211974 | UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; p->sParse.db = p->db; | | | < | 213192 213193 213194 213195 213196 213197 213198 213199 213200 213201 213202 213203 213204 213205 213206 213207 | UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; p->sParse.db = p->db; if( jsonArgIsJsonb(argv[0], &p->sParse) ){ /* We have JSONB */ }else{ p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); p->sParse.nJson = sqlite3_value_bytes(argv[0]); if( p->sParse.zJson==0 ){ p->i = p->iEnd = 0; return SQLITE_OK; } |
︙ | ︙ | |||
212294 212295 212296 212297 212298 212299 212300 212301 212302 212303 212304 212305 212306 212307 | #elif !defined(NDEBUG) # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif #endif /* !defined(SQLITE_AMALGAMATION) */ /* Macro to check for 4-byte alignment. Only used inside of assert() */ #ifdef SQLITE_DEBUG # define FOUR_BYTE_ALIGNED(X) ((((char*)(X) - (char*)0) & 3)==0) #endif | > > > > > > > > | 213517 213518 213519 213520 213521 213522 213523 213524 213525 213526 213527 213528 213529 213530 213531 213532 213533 213534 213535 213536 213537 213538 | #elif !defined(NDEBUG) # define ALWAYS(X) ((X)?1:(assert(0),0)) # define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) #endif #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY #else # define FLEXARRAY 1 #endif #endif /* !defined(SQLITE_AMALGAMATION) */ /* Macro to check for 4-byte alignment. Only used inside of assert() */ #ifdef SQLITE_DEBUG # define FOUR_BYTE_ALIGNED(X) ((((char*)(X) - (char*)0) & 3)==0) #endif |
︙ | ︙ | |||
212614 212615 212616 212617 212618 212619 212620 | ** operand to the MATCH operator of an R-Tree. */ struct RtreeMatchArg { u32 iSize; /* Size of this object */ RtreeGeomCallback cb; /* Info about the callback functions */ int nParam; /* Number of parameters to the SQL function */ sqlite3_value **apSqlParam; /* Original SQL parameter values */ | | > > > > | 213845 213846 213847 213848 213849 213850 213851 213852 213853 213854 213855 213856 213857 213858 213859 213860 213861 213862 213863 213864 213865 | ** operand to the MATCH operator of an R-Tree. */ struct RtreeMatchArg { u32 iSize; /* Size of this object */ RtreeGeomCallback cb; /* Info about the callback functions */ int nParam; /* Number of parameters to the SQL function */ sqlite3_value **apSqlParam; /* Original SQL parameter values */ RtreeDValue aParam[FLEXARRAY]; /* Values for parameters to the SQL function */ }; /* Size of an RtreeMatchArg object with N parameters */ #define SZ_RTREEMATCHARG(N) \ (offsetof(RtreeMatchArg,aParam)+(N)*sizeof(RtreeDValue)) #ifndef MAX # define MAX(x,y) ((x) < (y) ? (y) : (x)) #endif #ifndef MIN # define MIN(x,y) ((x) > (y) ? (y) : (x)) #endif |
︙ | ︙ | |||
214305 214306 214307 214308 214309 214310 214311 | pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; pIdxInfo->estimatedRows = nRow; return rc; } /* | | | 215540 215541 215542 215543 215544 215545 215546 215547 215548 215549 215550 215551 215552 215553 215554 | pIdxInfo->estimatedCost = (double)6.0 * (double)nRow; pIdxInfo->estimatedRows = nRow; return rc; } /* ** Return the N-dimensional volume of the cell stored in *p. */ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ RtreeDValue area = (RtreeDValue)1; assert( pRtree->nDim>=1 && pRtree->nDim<=5 ); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ switch( pRtree->nDim ){ |
︙ | ︙ | |||
216071 216072 216073 216074 216075 216076 216077 | va_end(ap); return pRet; } /* ** The second and subsequent arguments to this function are a printf() ** style format string and arguments. This function formats the string and | | | 217306 217307 217308 217309 217310 217311 217312 217313 217314 217315 217316 217317 217318 217319 217320 | va_end(ap); return pRet; } /* ** The second and subsequent arguments to this function are a printf() ** style format string and arguments. This function formats the string and ** appends it to the report being accumulated in pCheck. */ static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ va_list ap; va_start(ap, zFmt); if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){ char *z = sqlite3_vmprintf(zFmt, ap); if( z==0 ){ |
︙ | ︙ | |||
217259 217260 217261 217262 217263 217264 217265 | } /* ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). ** Returns: ** | | | 218494 218495 218496 218497 218498 218499 218500 218501 218502 218503 218504 218505 218506 218507 218508 | } /* ** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). ** Returns: ** ** +2 x0,y0 is on the line segment ** ** +1 x0,y0 is beneath line segment ** ** 0 x0,y0 is not on or beneath the line segment or the line segment ** is vertical and x0,y0 is not on the line segment ** ** The left-most coordinate min(x1,x2) is not considered to be part of |
︙ | ︙ | |||
217365 217366 217367 217368 217369 217370 217371 | sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); } } sqlite3_free(p1); sqlite3_free(p2); } | | | 218600 218601 218602 218603 218604 218605 218606 218607 218608 218609 218610 218611 218612 218613 218614 | sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); } } sqlite3_free(p1); sqlite3_free(p2); } /* Objects used by the overlap algorithm. */ typedef struct GeoEvent GeoEvent; typedef struct GeoSegment GeoSegment; typedef struct GeoOverlap GeoOverlap; struct GeoEvent { double x; /* X coordinate at which event occurs */ int eType; /* 0 for ADD, 1 for REMOVE */ GeoSegment *pSeg; /* The segment to be added or removed */ |
︙ | ︙ | |||
218412 218413 218414 218415 218416 218417 218418 | */ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); RtreeMatchArg *pBlob; sqlite3_int64 nBlob; int memErr = 0; | < | | 219647 219648 219649 219650 219651 219652 219653 219654 219655 219656 219657 219658 219659 219660 219661 | */ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); RtreeMatchArg *pBlob; sqlite3_int64 nBlob; int memErr = 0; nBlob = SZ_RTREEMATCHARG(nArg) + nArg*sizeof(sqlite3_value*); pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); if( !pBlob ){ sqlite3_result_error_nomem(ctx); }else{ int i; pBlob->iSize = nBlob; pBlob->cb = pGeomCtx[0]; |
︙ | ︙ | |||
219508 219509 219510 219511 219512 219513 219514 | ** mobile device that is frequently rebooted. Even after the writer process ** has committed one or more sub-transactions, other database clients continue ** to read from the original database snapshot. In other words, partially ** applied transactions are not visible to other clients. ** ** "RBU" stands for "Resumable Bulk Update". As in a large database update ** transmitted via a wireless network to a mobile device. A transaction | | | 220742 220743 220744 220745 220746 220747 220748 220749 220750 220751 220752 220753 220754 220755 220756 | ** mobile device that is frequently rebooted. Even after the writer process ** has committed one or more sub-transactions, other database clients continue ** to read from the original database snapshot. In other words, partially ** applied transactions are not visible to other clients. ** ** "RBU" stands for "Resumable Bulk Update". As in a large database update ** transmitted via a wireless network to a mobile device. A transaction ** applied using this extension is hence referred to as an "RBU update". ** ** ** LIMITATIONS ** ** An "RBU update" transaction is subject to the following limitations: ** ** * The transaction must consist of INSERT, UPDATE and DELETE operations |
︙ | ︙ | |||
219805 219806 219807 219808 219809 219810 219811 | ** This function does not delete the state database after an RBU vacuum ** is completed, even if it created it. However, if the call to ** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents ** of the state tables within the state database are zeroed. This way, ** the next call to sqlite3rbu_vacuum() opens a handle that starts a ** new RBU vacuum operation. ** | | | 221039 221040 221041 221042 221043 221044 221045 221046 221047 221048 221049 221050 221051 221052 221053 | ** This function does not delete the state database after an RBU vacuum ** is completed, even if it created it. However, if the call to ** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents ** of the state tables within the state database are zeroed. This way, ** the next call to sqlite3rbu_vacuum() opens a handle that starts a ** new RBU vacuum operation. ** ** As with sqlite3rbu_open(), Zipvfs users should refer to the comment ** describing the sqlite3rbu_create_vfs() API function below for ** a description of the complications associated with using RBU with ** zipvfs databases. */ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( const char *zTarget, const char *zState |
︙ | ︙ | |||
219901 219902 219903 219904 219905 219906 219907 | SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); /* ** Close an RBU handle. ** ** If the RBU update has been completely applied, mark the RBU database ** as fully applied. Otherwise, assuming no error has occurred, save the | | | 221135 221136 221137 221138 221139 221140 221141 221142 221143 221144 221145 221146 221147 221148 221149 | SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); /* ** Close an RBU handle. ** ** If the RBU update has been completely applied, mark the RBU database ** as fully applied. Otherwise, assuming no error has occurred, save the ** current state of the RBU update application to the RBU database. ** ** If an error has already occurred as part of an sqlite3rbu_step() ** or sqlite3rbu_open() call, or if one occurs within this function, an ** SQLite error code is returned. Additionally, if pzErrmsg is not NULL, ** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted ** English language error message. It is the responsibility of the caller to ** eventually free any such buffer using sqlite3_free(). |
︙ | ︙ | |||
224827 224828 224829 224830 224831 224832 224833 | static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; int rc; rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); /* If this is an RBU vacuum operation and this is the target database, ** pretend that it has at least one page. Otherwise, SQLite will not | | | 226061 226062 226063 226064 226065 226066 226067 226068 226069 226070 226071 226072 226073 226074 226075 | static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; int rc; rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); /* If this is an RBU vacuum operation and this is the target database, ** pretend that it has at least one page. Otherwise, SQLite will not ** check for the existence of a *-wal file. rbuVfsRead() contains ** similar logic. */ if( rc==SQLITE_OK && *pSize==0 && p->pRbu && rbuIsVacuum(p->pRbu) && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ *pSize = 1024; } |
︙ | ︙ | |||
226759 226760 226761 226762 226763 226764 226765 | if( sqlite3_value_type(argv[3])!=SQLITE_BLOB || sqlite3_value_bytes(argv[3])!=szPage ){ if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){ /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and ** all subsequent pages to be deleted. */ pTab->iDbTrunc = iDb; | < | > | 227993 227994 227995 227996 227997 227998 227999 228000 228001 228002 228003 228004 228005 228006 228007 228008 | if( sqlite3_value_type(argv[3])!=SQLITE_BLOB || sqlite3_value_bytes(argv[3])!=szPage ){ if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert && pgno>1 ){ /* "INSERT INTO dbpage($PGNO,NULL)" causes page number $PGNO and ** all subsequent pages to be deleted. */ pTab->iDbTrunc = iDb; pTab->pgnoTrunc = pgno-1; pgno = 1; }else{ zErr = "bad page value"; goto update_fail; } } if( dbpageBeginTrans(pTab)!=SQLITE_OK ){ |
︙ | ︙ | |||
228057 228058 228059 228060 228061 228062 228063 | sqlite3_finalize(pStmt); return rc; } /* ** This function is called to initialize the SessionTable.nCol, azCol[] ** abPK[] and azDflt[] members of SessionTable object pTab. If these | | > > | 229291 229292 229293 229294 229295 229296 229297 229298 229299 229300 229301 229302 229303 229304 229305 229306 229307 229308 229309 229310 229311 229312 229313 229314 229315 229316 229317 229318 229319 229320 229321 229322 229323 229324 229325 | sqlite3_finalize(pStmt); return rc; } /* ** This function is called to initialize the SessionTable.nCol, azCol[] ** abPK[] and azDflt[] members of SessionTable object pTab. If these ** fields are already initialized, this function is a no-op. ** ** If an error occurs, an error code is stored in sqlite3_session.rc and ** non-zero returned. Or, if no error occurs but the table has no primary ** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to ** indicate that updates on this table should be ignored. SessionTable.abPK ** is set to NULL in this case. */ static int sessionInitTable( sqlite3_session *pSession, /* Optional session handle */ SessionTable *pTab, /* Table object to initialize */ sqlite3 *db, /* Database handle to read schema from */ const char *zDb /* Name of db - "main", "temp" etc. */ ){ int rc = SQLITE_OK; if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); sqlite3_free(pTab->azCol); pTab->abPK = 0; rc = sessionTableInfo(pSession, db, zDb, pTab->zName, &pTab->nCol, &pTab->nTotalCol, 0, &pTab->azCol, &pTab->azDflt, &pTab->aiIdx, &abPK, ((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0) ); if( rc==SQLITE_OK ){ int i; |
︙ | ︙ | |||
229083 229084 229085 229086 229087 229088 229089 229090 229091 229092 229093 229094 229095 229096 229097 229098 229099 229100 | if( pzErrMsg ) *pzErrMsg = 0; if( rc==SQLITE_OK ){ char *zExpr = 0; sqlite3 *db = pSession->db; SessionTable *pTo; /* Table zTbl */ /* Locate and if necessary initialize the target table object */ rc = sessionFindTable(pSession, zTbl, &pTo); if( pTo==0 ) goto diff_out; if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ rc = pSession->rc; goto diff_out; } /* Check the table schemas match */ if( rc==SQLITE_OK ){ int bHasPk = 0; int bMismatch = 0; | > > | | > > > > > > > > > > > > > > > > > > | | | | > > > > > > > | > | 230319 230320 230321 230322 230323 230324 230325 230326 230327 230328 230329 230330 230331 230332 230333 230334 230335 230336 230337 230338 230339 230340 230341 230342 230343 230344 230345 230346 230347 230348 230349 230350 230351 230352 230353 230354 230355 230356 230357 230358 230359 230360 230361 230362 230363 230364 230365 230366 230367 230368 230369 230370 230371 230372 230373 230374 230375 230376 230377 230378 230379 230380 230381 230382 | if( pzErrMsg ) *pzErrMsg = 0; if( rc==SQLITE_OK ){ char *zExpr = 0; sqlite3 *db = pSession->db; SessionTable *pTo; /* Table zTbl */ /* Locate and if necessary initialize the target table object */ pSession->bAutoAttach++; rc = sessionFindTable(pSession, zTbl, &pTo); pSession->bAutoAttach--; if( pTo==0 ) goto diff_out; if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ rc = pSession->rc; goto diff_out; } /* Check the table schemas match */ if( rc==SQLITE_OK ){ int bHasPk = 0; int bMismatch = 0; int nCol = 0; /* Columns in zFrom.zTbl */ int bRowid = 0; u8 *abPK = 0; const char **azCol = 0; char *zDbExists = 0; /* Check that database zFrom is attached. */ zDbExists = sqlite3_mprintf("SELECT * FROM %Q.sqlite_schema", zFrom); if( zDbExists==0 ){ rc = SQLITE_NOMEM; }else{ sqlite3_stmt *pDbExists = 0; rc = sqlite3_prepare_v2(db, zDbExists, -1, &pDbExists, 0); if( rc==SQLITE_ERROR ){ rc = SQLITE_OK; nCol = -1; } sqlite3_finalize(pDbExists); sqlite3_free(zDbExists); } if( rc==SQLITE_OK && nCol==0 ){ rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, 0, &azCol, 0, 0, &abPK, pSession->bImplicitPK ? &bRowid : 0 ); } if( rc==SQLITE_OK ){ if( pTo->nCol!=nCol ){ if( nCol<=0 ){ rc = SQLITE_SCHEMA; if( pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("no such table: %s.%s", zFrom, zTbl); } }else{ bMismatch = 1; } }else{ int i; for(i=0; i<nCol; i++){ if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1; if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1; if( abPK[i] ) bHasPk = 1; } |
︙ | ︙ | |||
229880 229881 229882 229883 229884 229885 229886 | int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut, /* First argument for xOutput */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ sqlite3 *db = pSession->db; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ | | | 231144 231145 231146 231147 231148 231149 231150 231151 231152 231153 231154 231155 231156 231157 231158 | int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut, /* First argument for xOutput */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ sqlite3 *db = pSession->db; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ SessionBuffer buf = {0,0,0}; /* Buffer in which to accumulate changeset */ int rc; /* Return code */ assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) ); assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) ); /* Zero the output variables in case an error occurs. If this session ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), |
︙ | ︙ | |||
234314 234315 234316 234317 234318 234319 234320 234321 234322 234323 234324 234325 234326 234327 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) #else # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif #endif /* Truncate very long tokens to this many bytes. Hard limit is ** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset ** field that occurs at the start of each leaf page (see fts5_index.c). */ #define FTS5_MAX_TOKEN_SIZE 32768 | > > > > > > > > > > > > | 235578 235579 235580 235581 235582 235583 235584 235585 235586 235587 235588 235589 235590 235591 235592 235593 235594 235595 235596 235597 235598 235599 235600 235601 235602 235603 | #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) #else # define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) #endif /* ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof # define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY #else # define FLEXARRAY 1 #endif #endif /* Truncate very long tokens to this many bytes. Hard limit is ** (65536-1-1-4-9)==65521 bytes. The limiting factor is the 16-bit offset ** field that occurs at the start of each leaf page (see fts5_index.c). */ #define FTS5_MAX_TOKEN_SIZE 32768 |
︙ | ︙ | |||
234386 234387 234388 234389 234390 234391 234392 | ** then an object of the following type is used to record the set of columns. ** Each entry in the aiCol[] array is a column that may be matched. ** ** This object is used by fts5_expr.c and fts5_index.c. */ struct Fts5Colset { int nCol; | | | > | 235662 235663 235664 235665 235666 235667 235668 235669 235670 235671 235672 235673 235674 235675 235676 235677 235678 235679 235680 | ** then an object of the following type is used to record the set of columns. ** Each entry in the aiCol[] array is a column that may be matched. ** ** This object is used by fts5_expr.c and fts5_index.c. */ struct Fts5Colset { int nCol; int aiCol[FLEXARRAY]; }; /* Size (int bytes) of a complete Fts5Colset object with N columns. */ #define SZ_FTS5COLSET(N) (sizeof(i64)*((N+2)/2)) /************************************************************************** ** Interface to code in fts5_config.c. fts5_config.c contains contains code ** to parse the arguments passed to the CREATE VIRTUAL TABLE statement. */ typedef struct Fts5Config Fts5Config; |
︙ | ︙ | |||
235218 235219 235220 235221 235222 235223 235224 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Driver template for the LEMON parser generator. ** ** The "lemon" program processes an LALR(1) input grammar file, then uses ** this template to construct a parser. The "lemon" program inserts text | | | 236495 236496 236497 236498 236499 236500 236501 236502 236503 236504 236505 236506 236507 236508 236509 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Driver template for the LEMON parser generator. ** ** The "lemon" program processes an LALR(1) input grammar file, then uses ** this template to construct a parser. The "lemon" program inserts text ** at each "%%" line. Also, any "P-a-r-s-e" identifier prefix (without the ** interstitial "-" characters) contained in this template is changed into ** the value of the %name directive from the grammar. Otherwise, the content ** of this template is copied straight through into the generate parser ** source file. ** ** The following is the concatenation of all %include directives from the ** input grammar file: |
︙ | ︙ | |||
237372 237373 237374 237375 237376 237377 237378 | ** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) ) ** ** where "N" is the total number of documents in the set and nHit ** is the number that contain at least one instance of the phrase ** under consideration. ** ** The problem with this is that if (N < 2*nHit), the IDF is | | | 238649 238650 238651 238652 238653 238654 238655 238656 238657 238658 238659 238660 238661 238662 238663 | ** IDF = log( (N - nHit + 0.5) / (nHit + 0.5) ) ** ** where "N" is the total number of documents in the set and nHit ** is the number that contain at least one instance of the phrase ** under consideration. ** ** The problem with this is that if (N < 2*nHit), the IDF is ** negative. Which is undesirable. So the minimum allowable IDF is ** (1e-6) - roughly the same as a term that appears in just over ** half of set of 5,000,000 documents. */ double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) ); if( idf<=0.0 ) idf = 1e-6; p->aIDF[i] = idf; } } |
︙ | ︙ | |||
237835 237836 237837 237838 237839 237840 237841 | ** Return true if character 't' may be part of an FTS5 bareword, or false ** otherwise. Characters that may be part of barewords: ** ** * All non-ASCII characters, ** * The 52 upper and lower case ASCII characters, and ** * The 10 integer ASCII characters. ** * The underscore character "_" (0x5F). | | | 239112 239113 239114 239115 239116 239117 239118 239119 239120 239121 239122 239123 239124 239125 239126 | ** Return true if character 't' may be part of an FTS5 bareword, or false ** otherwise. Characters that may be part of barewords: ** ** * All non-ASCII characters, ** * The 52 upper and lower case ASCII characters, and ** * The 10 integer ASCII characters. ** * The underscore character "_" (0x5F). ** * The unicode "substitute" character (0x1A). */ static int sqlite3Fts5IsBareword(char t){ u8 aBareword[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 .. 0x2F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30 .. 0x3F */ |
︙ | ︙ | |||
239153 239154 239155 239156 239157 239158 239159 | i64 iRowid; /* Current rowid */ Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */ /* Child nodes. For a NOT node, this array always contains 2 entries. For ** AND or OR nodes, it contains 2 or more entries. */ int nChild; /* Number of child nodes */ | | > > > > | 240430 240431 240432 240433 240434 240435 240436 240437 240438 240439 240440 240441 240442 240443 240444 240445 240446 240447 240448 240449 | i64 iRowid; /* Current rowid */ Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */ /* Child nodes. For a NOT node, this array always contains 2 entries. For ** AND or OR nodes, it contains 2 or more entries. */ int nChild; /* Number of child nodes */ Fts5ExprNode *apChild[FLEXARRAY]; /* Array of child nodes */ }; /* Size (in bytes) of an Fts5ExprNode object that holds up to N children */ #define SZ_FTS5EXPRNODE(N) \ (offsetof(Fts5ExprNode,apChild) + (N)*sizeof(Fts5ExprNode*)) #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING) /* ** Invoke the xNext method of an Fts5ExprNode object. This macro should be ** used as if it has the same signature as the xNext() methods themselves. */ |
︙ | ︙ | |||
239186 239187 239188 239189 239190 239191 239192 | ** A phrase. One or more terms that must appear in a contiguous sequence ** within a document for it to match. */ struct Fts5ExprPhrase { Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */ Fts5Buffer poslist; /* Current position list */ int nTerm; /* Number of entries in aTerm[] */ | | > > > > | > > > | 240467 240468 240469 240470 240471 240472 240473 240474 240475 240476 240477 240478 240479 240480 240481 240482 240483 240484 240485 240486 240487 240488 240489 240490 240491 240492 240493 240494 240495 240496 240497 240498 240499 240500 240501 | ** A phrase. One or more terms that must appear in a contiguous sequence ** within a document for it to match. */ struct Fts5ExprPhrase { Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */ Fts5Buffer poslist; /* Current position list */ int nTerm; /* Number of entries in aTerm[] */ Fts5ExprTerm aTerm[FLEXARRAY]; /* Terms that make up this phrase */ }; /* Size (in bytes) of an Fts5ExprPhrase object that holds up to N terms */ #define SZ_FTS5EXPRPHRASE(N) \ (offsetof(Fts5ExprPhrase,aTerm) + (N)*sizeof(Fts5ExprTerm)) /* ** One or more phrases that must appear within a certain token distance of ** each other within each matching document. */ struct Fts5ExprNearset { int nNear; /* NEAR parameter */ Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */ int nPhrase; /* Number of entries in aPhrase[] array */ Fts5ExprPhrase *apPhrase[FLEXARRAY]; /* Array of phrase pointers */ }; /* Size (in bytes) of an Fts5ExprNearset object covering up to N phrases */ #define SZ_FTS5EXPRNEARSET(N) \ (offsetof(Fts5ExprNearset,apPhrase)+(N)*sizeof(Fts5ExprPhrase*)) /* ** Parse context. */ struct Fts5Parse { Fts5Config *pConfig; char *zErr; |
︙ | ︙ | |||
239359 239360 239361 239362 239363 239364 239365 | assert( sParse.pExpr || sParse.rc!=SQLITE_OK ); assert_expr_depth_ok(sParse.rc, sParse.pExpr); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){ | | | 240647 240648 240649 240650 240651 240652 240653 240654 240655 240656 240657 240658 240659 240660 240661 | assert( sParse.pExpr || sParse.rc!=SQLITE_OK ); assert_expr_depth_ok(sParse.rc, sParse.pExpr); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){ int n = SZ_FTS5COLSET(1); Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); if( pColset ){ pColset->nCol = 1; pColset->aiCol[0] = iCol; sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset); } } |
︙ | ︙ | |||
240717 240718 240719 240720 240721 240722 240723 | ){ const int SZALLOC = 8; Fts5ExprNearset *pRet = 0; if( pParse->rc==SQLITE_OK ){ if( pNear==0 ){ sqlite3_int64 nByte; | | | | 242005 242006 242007 242008 242009 242010 242011 242012 242013 242014 242015 242016 242017 242018 242019 242020 242021 242022 242023 242024 242025 242026 242027 242028 242029 242030 | ){ const int SZALLOC = 8; Fts5ExprNearset *pRet = 0; if( pParse->rc==SQLITE_OK ){ if( pNear==0 ){ sqlite3_int64 nByte; nByte = SZ_FTS5EXPRNEARSET(SZALLOC+1); pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; }else{ memset(pRet, 0, (size_t)nByte); } }else if( (pNear->nPhrase % SZALLOC)==0 ){ int nNew = pNear->nPhrase + SZALLOC; sqlite3_int64 nByte; nByte = SZ_FTS5EXPRNEARSET(nNew+1); pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; } }else{ pRet = pNear; } |
︙ | ︙ | |||
240819 240820 240821 240822 240823 240824 240825 | }else{ Fts5ExprTerm *pTerm; if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){ Fts5ExprPhrase *pNew; int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0); pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, | | | | 242107 242108 242109 242110 242111 242112 242113 242114 242115 242116 242117 242118 242119 242120 242121 242122 242123 242124 242125 242126 | }else{ Fts5ExprTerm *pTerm; if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){ Fts5ExprPhrase *pNew; int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0); pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, SZ_FTS5EXPRPHRASE(nNew+1) ); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ if( pPhrase==0 ) memset(pNew, 0, SZ_FTS5EXPRPHRASE(1)); pCtx->pPhrase = pPhrase = pNew; pNew->nTerm = nNew - SZALLOC; } } if( rc==SQLITE_OK ){ pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; |
︙ | ︙ | |||
240932 240933 240934 240935 240936 240937 240938 | } pParse->nPhrase++; } if( sCtx.pPhrase==0 ){ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ | | | 242220 242221 242222 242223 242224 242225 242226 242227 242228 242229 242230 242231 242232 242233 242234 | } pParse->nPhrase++; } if( sCtx.pPhrase==0 ){ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, SZ_FTS5EXPRPHRASE(1)); }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } assert( pParse->apPhrase!=0 ); pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } |
︙ | ︙ | |||
240967 240968 240969 240970 240971 240972 240973 | pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); } if( rc==SQLITE_OK ){ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase*)); } if( rc==SQLITE_OK ){ | | < | | | 242255 242256 242257 242258 242259 242260 242261 242262 242263 242264 242265 242266 242267 242268 242269 242270 242271 242272 242273 242274 242275 242276 242277 242278 242279 242280 | pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); } if( rc==SQLITE_OK ){ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase*)); } if( rc==SQLITE_OK ){ pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRNODE(1)); } if( rc==SQLITE_OK ){ pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRNEARSET(2)); } if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ sqlite3_int64 nByte; Fts5Colset *pColset; nByte = SZ_FTS5COLSET(pColsetOrig->nCol); pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); if( pColset ){ memcpy(pColset, pColsetOrig, (size_t)nByte); } pNew->pRoot->pNear->pColset = pColset; } } |
︙ | ︙ | |||
241007 241008 241009 241010 241011 241012 241013 | sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; } } }else{ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ | | | 242294 242295 242296 242297 242298 242299 242300 242301 242302 242303 242304 242305 242306 242307 242308 | sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; } } }else{ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRPHRASE(1)); } } if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ /* All the allocations succeeded. Put the expression object together. */ pNew->pIndex = pExpr->pIndex; pNew->pConfig = pExpr->pConfig; |
︙ | ︙ | |||
241072 241073 241074 241075 241076 241077 241078 | char c = (char)p->p[i]; if( c<'0' || c>'9' ){ sqlite3Fts5ParseError( pParse, "expected integer, got \"%.*s\"", p->n, p->p ); return; } | | > | 242359 242360 242361 242362 242363 242364 242365 242366 242367 242368 242369 242370 242371 242372 242373 242374 | char c = (char)p->p[i]; if( c<'0' || c>'9' ){ sqlite3Fts5ParseError( pParse, "expected integer, got \"%.*s\"", p->n, p->p ); return; } if( nNear<214748363 ) nNear = nNear * 10 + (p->p[i] - '0'); /* ^^^^^^^^^^^^^^^--- Prevent integer overflow */ } }else{ nNear = FTS5_DEFAULT_NEARDIST; } pNear->nNear = nNear; } } |
︙ | ︙ | |||
241101 241102 241103 241104 241105 241106 241107 | ){ int nCol = p ? p->nCol : 0; /* Num. columns already in colset object */ Fts5Colset *pNew; /* New colset object to return */ assert( pParse->rc==SQLITE_OK ); assert( iCol>=0 && iCol<pParse->pConfig->nCol ); | | | 242389 242390 242391 242392 242393 242394 242395 242396 242397 242398 242399 242400 242401 242402 242403 | ){ int nCol = p ? p->nCol : 0; /* Num. columns already in colset object */ Fts5Colset *pNew; /* New colset object to return */ assert( pParse->rc==SQLITE_OK ); assert( iCol>=0 && iCol<pParse->pConfig->nCol ); pNew = sqlite3_realloc64(p, SZ_FTS5COLSET(nCol+1)); if( pNew==0 ){ pParse->rc = SQLITE_NOMEM; }else{ int *aiCol = pNew->aiCol; int i, j; for(i=0; i<nCol; i++){ if( aiCol[i]==iCol ) return pNew; |
︙ | ︙ | |||
241136 241137 241138 241139 241140 241141 241142 | ** as the second argument before returning. */ static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){ Fts5Colset *pRet; int nCol = pParse->pConfig->nCol; pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, | | | 242424 242425 242426 242427 242428 242429 242430 242431 242432 242433 242434 242435 242436 242437 242438 | ** as the second argument before returning. */ static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){ Fts5Colset *pRet; int nCol = pParse->pConfig->nCol; pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, SZ_FTS5COLSET(nCol+1) ); if( pRet ){ int i; int iOld = 0; for(i=0; i<nCol; i++){ if( iOld>=p->nCol || p->aiCol[iOld]!=i ){ pRet->aiCol[pRet->nCol++] = i; |
︙ | ︙ | |||
241197 241198 241199 241200 241201 241202 241203 | ** Otherwise, a copy of (*pOrig) is made into memory obtained from ** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation ** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned. */ static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ Fts5Colset *pRet; if( pOrig ){ | | | 242485 242486 242487 242488 242489 242490 242491 242492 242493 242494 242495 242496 242497 242498 242499 | ** Otherwise, a copy of (*pOrig) is made into memory obtained from ** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation ** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned. */ static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ Fts5Colset *pRet; if( pOrig ){ sqlite3_int64 nByte = SZ_FTS5COLSET(pOrig->nCol); pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); if( pRet ){ memcpy(pRet, pOrig, (size_t)nByte); } }else{ pRet = 0; } |
︙ | ︙ | |||
241365 241366 241367 241368 241369 241370 241371 | int ii; int nByte; Fts5ExprNode *pRet; assert( pNear->nPhrase==1 ); assert( pParse->bPhraseToAnd ); | | | | 242653 242654 242655 242656 242657 242658 242659 242660 242661 242662 242663 242664 242665 242666 242667 242668 242669 242670 242671 242672 242673 242674 242675 242676 242677 | int ii; int nByte; Fts5ExprNode *pRet; assert( pNear->nPhrase==1 ); assert( pParse->bPhraseToAnd ); nByte = SZ_FTS5EXPRNODE(nTerm+1); pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ pRet->eType = FTS5_AND; pRet->nChild = nTerm; pRet->iHeight = 1; fts5ExprAssignXNext(pRet); pParse->nPhrase--; for(ii=0; ii<nTerm; ii++){ Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero( &pParse->rc, SZ_FTS5EXPRPHRASE(1) ); if( pPhrase ){ if( parseGrowPhraseArray(pParse) ){ fts5ExprPhraseFree(pPhrase); }else{ Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii]; Fts5ExprTerm *pTo = &pPhrase->aTerm[0]; |
︙ | ︙ | |||
241444 241445 241446 241447 241448 241449 241450 | nChild = 2; }else if( eType==FTS5_AND || eType==FTS5_OR ){ nChild = 2; if( pLeft->eType==eType ) nChild += pLeft->nChild-1; if( pRight->eType==eType ) nChild += pRight->nChild-1; } | | | 242732 242733 242734 242735 242736 242737 242738 242739 242740 242741 242742 242743 242744 242745 242746 | nChild = 2; }else if( eType==FTS5_AND || eType==FTS5_OR ){ nChild = 2; if( pLeft->eType==eType ) nChild += pLeft->nChild-1; if( pRight->eType==eType ) nChild += pRight->nChild-1; } nByte = SZ_FTS5EXPRNODE(nChild); pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ pRet->eType = eType; pRet->pNear = pNear; fts5ExprAssignXNext(pRet); if( eType==FTS5_STRING ){ |
︙ | ︙ | |||
242319 242320 242321 242322 242323 242324 242325 | *ppOut = pTerm->pTerm; *pnOut = pTerm->nFullTerm; } return rc; } /* | | | 243607 243608 243609 243610 243611 243612 243613 243614 243615 243616 243617 243618 243619 243620 243621 | *ppOut = pTerm->pTerm; *pnOut = pTerm->nFullTerm; } return rc; } /* ** Clear the token mappings for all Fts5IndexIter objects managed by ** the expression passed as the only argument. */ static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ int ii; for(ii=0; ii<pExpr->nPhrase; ii++){ Fts5ExprTerm *pT; for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){ |
︙ | ︙ | |||
242354 242355 242356 242357 242358 242359 242360 | /* #include "fts5Int.h" */ typedef struct Fts5HashEntry Fts5HashEntry; /* ** This file contains the implementation of an in-memory hash table used | | | 243642 243643 243644 243645 243646 243647 243648 243649 243650 243651 243652 243653 243654 243655 243656 | /* #include "fts5Int.h" */ typedef struct Fts5HashEntry Fts5HashEntry; /* ** This file contains the implementation of an in-memory hash table used ** to accumulate "term -> doclist" content before it is flushed to a level-0 ** segment. */ struct Fts5Hash { int eDetail; /* Copy of Fts5Config.eDetail */ int *pnByte; /* Pointer to bytes counter */ |
︙ | ︙ | |||
242411 242412 242413 242414 242415 242416 242417 | u8 bContent; /* Set content-flag (detail=none mode) */ i16 iCol; /* Column of last value written */ int iPos; /* Position of last value written */ i64 iRowid; /* Rowid of last value written */ }; /* | | | 243699 243700 243701 243702 243703 243704 243705 243706 243707 243708 243709 243710 243711 243712 243713 | u8 bContent; /* Set content-flag (detail=none mode) */ i16 iCol; /* Column of last value written */ int iPos; /* Position of last value written */ i64 iRowid; /* Rowid of last value written */ }; /* ** Equivalent to: ** ** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; } */ #define fts5EntryKey(p) ( ((char *)(&(p)[1])) ) /* |
︙ | ︙ | |||
243347 243348 243349 243350 243351 243352 243353 | }; struct Fts5Structure { int nRef; /* Object reference count */ u64 nWriteCounter; /* Total leaves written to level 0 */ u64 nOriginCntr; /* Origin value for next top-level segment */ int nSegment; /* Total segments in this structure */ int nLevel; /* Number of levels in this index */ | | > > > > | 244635 244636 244637 244638 244639 244640 244641 244642 244643 244644 244645 244646 244647 244648 244649 244650 244651 244652 244653 244654 244655 | }; struct Fts5Structure { int nRef; /* Object reference count */ u64 nWriteCounter; /* Total leaves written to level 0 */ u64 nOriginCntr; /* Origin value for next top-level segment */ int nSegment; /* Total segments in this structure */ int nLevel; /* Number of levels in this index */ Fts5StructureLevel aLevel[FLEXARRAY]; /* Array of nLevel level objects */ }; /* Size (in bytes) of an Fts5Structure object holding up to N levels */ #define SZ_FTS5STRUCTURE(N) \ (offsetof(Fts5Structure,aLevel) + (N)*sizeof(Fts5StructureLevel)) /* ** An object of type Fts5SegWriter is used to write to segments. */ struct Fts5PageWriter { int pgno; /* Page number for this page */ int iPrevPgidx; /* Previous value written into pgidx */ Fts5Buffer buf; /* Buffer containing leaf data */ |
︙ | ︙ | |||
243479 243480 243481 243482 243483 243484 243485 | u8 bDel; /* True if the delete flag is set */ }; /* ** Array of tombstone pages. Reference counted. */ struct Fts5TombstoneArray { | | | > > > > | 244771 244772 244773 244774 244775 244776 244777 244778 244779 244780 244781 244782 244783 244784 244785 244786 244787 244788 244789 244790 244791 244792 | u8 bDel; /* True if the delete flag is set */ }; /* ** Array of tombstone pages. Reference counted. */ struct Fts5TombstoneArray { int nRef; /* Number of pointers to this object */ int nTombstone; Fts5Data *apTombstone[FLEXARRAY]; /* Array of tombstone pages */ }; /* Size (in bytes) of an Fts5TombstoneArray holding up to N tombstones */ #define SZ_FTS5TOMBSTONEARRAY(N) \ (offsetof(Fts5TombstoneArray,apTombstone)+(N)*sizeof(Fts5Data*)) /* ** Argument is a pointer to an Fts5Data structure that contains a ** leaf page. */ #define ASSERT_SZLEAF_OK(x) assert( \ (x)->szLeaf==(x)->nn || (x)->szLeaf==fts5GetU16(&(x)->p[2]) \ |
︙ | ︙ | |||
243552 243553 243554 243555 243556 243557 243558 | int nSeg; /* Size of aSeg[] array */ int bRev; /* True to iterate in reverse order */ u8 bSkipEmpty; /* True to skip deleted entries */ i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ Fts5CResult *aFirst; /* Current merge state (see above) */ | | > > > | 244848 244849 244850 244851 244852 244853 244854 244855 244856 244857 244858 244859 244860 244861 244862 244863 244864 244865 244866 | int nSeg; /* Size of aSeg[] array */ int bRev; /* True to iterate in reverse order */ u8 bSkipEmpty; /* True to skip deleted entries */ i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ Fts5CResult *aFirst; /* Current merge state (see above) */ Fts5SegIter aSeg[FLEXARRAY]; /* Array of segment iterators */ }; /* Size (in bytes) of an Fts5Iter object holding up to N segment iterators */ #define SZ_FTS5ITER(N) (offsetof(Fts5Iter,aSeg)+(N)*sizeof(Fts5SegIter)) /* ** An instance of the following type is used to iterate through the contents ** of a doclist-index record. ** ** pData: ** Record containing the doclist-index data. |
︙ | ︙ | |||
243581 243582 243583 243584 243585 243586 243587 | /* Output variables */ int iLeafPgno; /* Page number of current leaf page */ i64 iRowid; /* First rowid on leaf iLeafPgno */ }; struct Fts5DlidxIter { int nLvl; int iSegid; | | > > > > | 244880 244881 244882 244883 244884 244885 244886 244887 244888 244889 244890 244891 244892 244893 244894 244895 244896 244897 244898 244899 | /* Output variables */ int iLeafPgno; /* Page number of current leaf page */ i64 iRowid; /* First rowid on leaf iLeafPgno */ }; struct Fts5DlidxIter { int nLvl; int iSegid; Fts5DlidxLvl aLvl[FLEXARRAY]; }; /* Size (in bytes) of an Fts5DlidxIter object with up to N levels */ #define SZ_FTS5DLIDXITER(N) \ (offsetof(Fts5DlidxIter,aLvl)+(N)*sizeof(Fts5DlidxLvl)) static void fts5PutU16(u8 *aOut, u16 iVal){ aOut[0] = (iVal>>8); aOut[1] = (iVal&0xFF); } static u16 fts5GetU16(const u8 *aIn){ |
︙ | ︙ | |||
243951 243952 243953 243954 243955 243956 243957 | ** ** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If ** an error occurs, (*pRc) is set to an SQLite error code before returning. */ static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){ Fts5Structure *p = *pp; if( *pRc==SQLITE_OK && p->nRef>1 ){ | | | 245254 245255 245256 245257 245258 245259 245260 245261 245262 245263 245264 245265 245266 245267 245268 | ** ** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If ** an error occurs, (*pRc) is set to an SQLite error code before returning. */ static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){ Fts5Structure *p = *pp; if( *pRc==SQLITE_OK && p->nRef>1 ){ i64 nByte = SZ_FTS5STRUCTURE(p->nLevel); Fts5Structure *pNew; pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte); if( pNew ){ int i; memcpy(pNew, p, nByte); for(i=0; i<p->nLevel; i++) pNew->aLevel[i].aSeg = 0; for(i=0; i<p->nLevel; i++){ |
︙ | ︙ | |||
244025 244026 244027 244028 244029 244030 244031 | i += fts5GetVarint32(&pData[i], nLevel); i += fts5GetVarint32(&pData[i], nSegment); if( nLevel>FTS5_MAX_SEGMENT || nLevel<0 || nSegment>FTS5_MAX_SEGMENT || nSegment<0 ){ return FTS5_CORRUPT; } | | < < < | 245328 245329 245330 245331 245332 245333 245334 245335 245336 245337 245338 245339 245340 245341 245342 | i += fts5GetVarint32(&pData[i], nLevel); i += fts5GetVarint32(&pData[i], nSegment); if( nLevel>FTS5_MAX_SEGMENT || nLevel<0 || nSegment>FTS5_MAX_SEGMENT || nSegment<0 ){ return FTS5_CORRUPT; } nByte = SZ_FTS5STRUCTURE(nLevel); pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte); if( pRet ){ pRet->nRef = 1; pRet->nLevel = nLevel; pRet->nSegment = nSegment; i += sqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter); |
︙ | ︙ | |||
244108 244109 244110 244111 244112 244113 244114 | */ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ fts5StructureMakeWritable(pRc, ppStruct); assert( (ppStruct!=0 && (*ppStruct)!=0) || (*pRc)!=SQLITE_OK ); if( *pRc==SQLITE_OK ){ Fts5Structure *pStruct = *ppStruct; int nLevel = pStruct->nLevel; | | < < < | 245408 245409 245410 245411 245412 245413 245414 245415 245416 245417 245418 245419 245420 245421 245422 | */ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ fts5StructureMakeWritable(pRc, ppStruct); assert( (ppStruct!=0 && (*ppStruct)!=0) || (*pRc)!=SQLITE_OK ); if( *pRc==SQLITE_OK ){ Fts5Structure *pStruct = *ppStruct; int nLevel = pStruct->nLevel; sqlite3_int64 nByte = SZ_FTS5STRUCTURE(nLevel+2); pStruct = sqlite3_realloc64(pStruct, nByte); if( pStruct ){ memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel)); pStruct->nLevel++; *ppStruct = pStruct; }else{ |
︙ | ︙ | |||
244650 244651 244652 244653 244654 244655 244656 | int iLeafPg /* Leaf page number to load dlidx for */ ){ Fts5DlidxIter *pIter = 0; int i; int bDone = 0; for(i=0; p->rc==SQLITE_OK && bDone==0; i++){ | | | 245947 245948 245949 245950 245951 245952 245953 245954 245955 245956 245957 245958 245959 245960 245961 | int iLeafPg /* Leaf page number to load dlidx for */ ){ Fts5DlidxIter *pIter = 0; int i; int bDone = 0; for(i=0; p->rc==SQLITE_OK && bDone==0; i++){ sqlite3_int64 nByte = SZ_FTS5DLIDXITER(i+1); Fts5DlidxIter *pNew; pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte); if( pNew==0 ){ p->rc = SQLITE_NOMEM; }else{ i64 iRowid = FTS5_DLIDX_ROWID(iSegid, i, iLeafPg); |
︙ | ︙ | |||
244868 244869 244870 244871 244872 244873 244874 | ** Allocate a tombstone hash page array object (pIter->pTombArray) for ** the iterator passed as the second argument. If an OOM error occurs, ** leave an error in the Fts5Index object. */ static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ const int nTomb = pIter->pSeg->nPgTombstone; if( nTomb>0 ){ | | | 246165 246166 246167 246168 246169 246170 246171 246172 246173 246174 246175 246176 246177 246178 246179 | ** Allocate a tombstone hash page array object (pIter->pTombArray) for ** the iterator passed as the second argument. If an OOM error occurs, ** leave an error in the Fts5Index object. */ static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ const int nTomb = pIter->pSeg->nPgTombstone; if( nTomb>0 ){ int nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1); Fts5TombstoneArray *pNew; pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ pNew->nTombstone = nTomb; pNew->nRef = 1; pIter->pTombArray = pNew; } |
︙ | ︙ | |||
246329 246330 246331 246332 246333 246334 246335 | int nSeg ){ Fts5Iter *pNew; i64 nSlot; /* Power of two >= nSeg */ for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2); pNew = fts5IdxMalloc(p, | | < | 247626 247627 247628 247629 247630 247631 247632 247633 247634 247635 247636 247637 247638 247639 247640 | int nSeg ){ Fts5Iter *pNew; i64 nSlot; /* Power of two >= nSeg */ for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2); pNew = fts5IdxMalloc(p, SZ_FTS5ITER(nSlot) + /* pNew + pNew->aSeg[] */ sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */ ); if( pNew ){ pNew->nSeg = nSlot; pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot]; pNew->pIndex = p; pNew->xSetOutputs = fts5IterSetOutputs_Noop; |
︙ | ︙ | |||
248696 248697 248698 248699 248700 248701 248702 | } static Fts5Structure *fts5IndexOptimizeStruct( Fts5Index *p, Fts5Structure *pStruct ){ Fts5Structure *pNew = 0; | | | 249992 249993 249994 249995 249996 249997 249998 249999 250000 250001 250002 250003 250004 250005 250006 | } static Fts5Structure *fts5IndexOptimizeStruct( Fts5Index *p, Fts5Structure *pStruct ){ Fts5Structure *pNew = 0; sqlite3_int64 nByte = SZ_FTS5STRUCTURE(1); int nSeg = pStruct->nSegment; int i; /* Figure out if this structure requires optimization. A structure does ** not require optimization if either: ** ** 1. it consists of fewer than two segments, or |
︙ | ︙ | |||
248726 248727 248728 248729 248730 248731 248732 248733 248734 248735 248736 248737 248738 248739 | fts5StructureRef(pStruct); return pStruct; } assert( pStruct->aLevel[i].nMerge<=nThis ); } nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel); pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ Fts5StructureLevel *pLvl; nByte = nSeg * sizeof(Fts5StructureSegment); pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL); pNew->nRef = 1; | > | 250022 250023 250024 250025 250026 250027 250028 250029 250030 250031 250032 250033 250034 250035 250036 | fts5StructureRef(pStruct); return pStruct; } assert( pStruct->aLevel[i].nMerge<=nThis ); } nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel); assert( nByte==SZ_FTS5STRUCTURE(pStruct->nLevel+2) ); pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ Fts5StructureLevel *pLvl; nByte = nSeg * sizeof(Fts5StructureSegment); pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL); pNew->nRef = 1; |
︙ | ︙ | |||
249302 249303 249304 249305 249306 249307 249308 | Fts5Buffer terms; /* The following are used for other full-token tokendata queries only. */ int nIter; int nIterAlloc; Fts5PoslistReader *aPoslistReader; int *aPoslistToIter; | | > > > > | 250599 250600 250601 250602 250603 250604 250605 250606 250607 250608 250609 250610 250611 250612 250613 250614 250615 250616 250617 250618 | Fts5Buffer terms; /* The following are used for other full-token tokendata queries only. */ int nIter; int nIterAlloc; Fts5PoslistReader *aPoslistReader; int *aPoslistToIter; Fts5Iter *apIter[FLEXARRAY]; }; /* Size in bytes of an Fts5TokenDataIter object holding up to N iterators */ #define SZ_FTS5TOKENDATAITER(N) \ (offsetof(Fts5TokenDataIter,apIter) + (N)*sizeof(Fts5Iter)) /* ** The two input arrays - a1[] and a2[] - are in sorted order. This function ** merges the two arrays together and writes the result to output array ** aOut[]. aOut[] is guaranteed to be large enough to hold the result. ** ** Duplicate entries are copied into the output. So the size of the output |
︙ | ︙ | |||
249376 249377 249378 249379 249380 249381 249382 | pT->nMap++; } } /* ** Sort the contents of the pT->aMap[] array. ** | | | 250677 250678 250679 250680 250681 250682 250683 250684 250685 250686 250687 250688 250689 250690 250691 | pT->nMap++; } } /* ** Sort the contents of the pT->aMap[] array. ** ** The sorting algorithm requires a malloc(). If this fails, an error code ** is left in Fts5Index.rc before returning. */ static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){ Fts5TokenDataMap *aTmp = 0; int nByte = pT->nMap * sizeof(Fts5TokenDataMap); aTmp = (Fts5TokenDataMap*)sqlite3Fts5MallocZero(&p->rc, nByte); |
︙ | ︙ | |||
249567 249568 249569 249570 249571 249572 249573 | s.iLastRowid = 0; s.nBuf = 32; if( iIdx==0 && p->pConfig->eDetail==FTS5_DETAIL_FULL && p->pConfig->bPrefixInsttoken ){ s.pTokendata = &s2; | | | 250868 250869 250870 250871 250872 250873 250874 250875 250876 250877 250878 250879 250880 250881 250882 | s.iLastRowid = 0; s.nBuf = 32; if( iIdx==0 && p->pConfig->eDetail==FTS5_DETAIL_FULL && p->pConfig->bPrefixInsttoken ){ s.pTokendata = &s2; s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, SZ_FTS5TOKENDATAITER(1)); } if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ s.xMerge = fts5MergeRowidLists; s.xAppend = fts5AppendRowid; }else{ s.nMerge = FTS5_MERGE_NLIST-1; |
︙ | ︙ | |||
249695 249696 249697 249698 249699 249700 249701 | /* ** The %_data table is completely empty when this function is called. This ** function populates it with the initial structure objects for each index, ** and the initial version of the "averages" record (a zero-byte blob). */ static int sqlite3Fts5IndexReinit(Fts5Index *p){ | | > | > | | | 250996 250997 250998 250999 251000 251001 251002 251003 251004 251005 251006 251007 251008 251009 251010 251011 251012 251013 251014 251015 251016 251017 251018 251019 251020 | /* ** The %_data table is completely empty when this function is called. This ** function populates it with the initial structure objects for each index, ** and the initial version of the "averages" record (a zero-byte blob). */ static int sqlite3Fts5IndexReinit(Fts5Index *p){ Fts5Structure *pTmp; u8 tmpSpace[SZ_FTS5STRUCTURE(1)]; fts5StructureInvalidate(p); fts5IndexDiscardData(p); pTmp = (Fts5Structure*)tmpSpace; memset(pTmp, 0, SZ_FTS5STRUCTURE(1)); if( p->pConfig->bContentlessDelete ){ pTmp->nOriginCntr = 1; } fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); fts5StructureWrite(p, pTmp); return fts5IndexReturn(p); } /* ** Open a new Fts5Index handle. If the bCreate argument is true, create ** and initialize the underlying %_data table. ** |
︙ | ︙ | |||
249911 249912 249913 249914 249915 249916 249917 | Fts5Iter *pAppend /* Append this iterator */ ){ Fts5TokenDataIter *pRet = pIn; if( p->rc==SQLITE_OK ){ if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; | | | 251214 251215 251216 251217 251218 251219 251220 251221 251222 251223 251224 251225 251226 251227 251228 | Fts5Iter *pAppend /* Append this iterator */ ){ Fts5TokenDataIter *pRet = pIn; if( p->rc==SQLITE_OK ){ if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1); Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); if( pNew==0 ){ p->rc = SQLITE_NOMEM; }else{ if( pIn==0 ) memset(pNew, 0, nByte); pRet = pNew; |
︙ | ︙ | |||
250427 250428 250429 250430 250431 250432 250433 | Fts5Buffer token = {0, 0, 0}; TokendataSetupCtx ctx; memset(&ctx, 0, sizeof(ctx)); fts5BufferGrow(&p->rc, &token, nToken+1); assert( token.p!=0 || p->rc!=SQLITE_OK ); | | > | 251730 251731 251732 251733 251734 251735 251736 251737 251738 251739 251740 251741 251742 251743 251744 251745 | Fts5Buffer token = {0, 0, 0}; TokendataSetupCtx ctx; memset(&ctx, 0, sizeof(ctx)); fts5BufferGrow(&p->rc, &token, nToken+1); assert( token.p!=0 || p->rc!=SQLITE_OK ); ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, SZ_FTS5TOKENDATAITER(1)); if( p->rc==SQLITE_OK ){ /* Fill in the token prefix to search for */ token.p[0] = FTS5_MAIN_PREFIX; memcpy(&token.p[1], pToken, nToken); token.n = nToken+1; |
︙ | ︙ | |||
250558 250559 250560 250561 250562 250563 250564 | i64 iPos = (((i64)iCol)<<32) + iOff; assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); assert( pIter->pTokenDataIter || pIter->nSeg>0 ); if( pIter->nSeg>0 ){ /* This is a prefix term iterator. */ if( pT==0 ){ | | > | 251862 251863 251864 251865 251866 251867 251868 251869 251870 251871 251872 251873 251874 251875 251876 251877 | i64 iPos = (((i64)iCol)<<32) + iOff; assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); assert( pIter->pTokenDataIter || pIter->nSeg>0 ); if( pIter->nSeg>0 ){ /* This is a prefix term iterator. */ if( pT==0 ){ pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, SZ_FTS5TOKENDATAITER(1)); pIter->pTokenDataIter = pT; } if( pT ){ fts5TokendataIterAppendMap(p, pT, pT->terms.n, nToken, iRowid, iPos); fts5BufferAppendBlob(&p->rc, &pT->terms, nToken, (const u8*)pToken); } }else{ |
︙ | ︙ | |||
251592 251593 251594 251595 251596 251597 251598 | *pbTombstone = (int)(iRowid & 0x0001); } #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ | | | 252897 252898 252899 252900 252901 252902 252903 252904 252905 252906 252907 252908 252909 252910 252911 | *pbTombstone = (int)(iRowid & 0x0001); } #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid components */ fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); if( iSegid==0 ){ if( iKey==FTS5_AVERAGES_ROWID ){ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} "); }else{ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}"); |
︙ | ︙ | |||
252553 252554 252555 252556 252557 252558 252559 | ** byte of the position list for the corresponding phrase. */ struct Fts5Sorter { sqlite3_stmt *pStmt; i64 iRowid; /* Current rowid */ const u8 *aPoslist; /* Position lists for current row */ int nIdx; /* Number of entries in aIdx[] */ | | > > | 253858 253859 253860 253861 253862 253863 253864 253865 253866 253867 253868 253869 253870 253871 253872 253873 253874 253875 253876 | ** byte of the position list for the corresponding phrase. */ struct Fts5Sorter { sqlite3_stmt *pStmt; i64 iRowid; /* Current rowid */ const u8 *aPoslist; /* Position lists for current row */ int nIdx; /* Number of entries in aIdx[] */ int aIdx[FLEXARRAY]; /* Offsets into aPoslist for current row */ }; /* Size (int bytes) of an Fts5Sorter object with N indexes */ #define SZ_FTS5SORTER(N) (offsetof(Fts5Sorter,nIdx)+((N+2)/2)*sizeof(i64)) /* ** Virtual-table cursor object. ** ** iSpecial: ** If this is a 'special' query (refer to function fts5SpecialMatch()), ** then this variable contains the result of the query. |
︙ | ︙ | |||
253433 253434 253435 253436 253437 253438 253439 | int nPhrase; sqlite3_int64 nByte; int rc; const char *zRank = pCsr->zRank; const char *zRankArgs = pCsr->zRankArgs; nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); | | | 254740 254741 254742 254743 254744 254745 254746 254747 254748 254749 254750 254751 254752 254753 254754 | int nPhrase; sqlite3_int64 nByte; int rc; const char *zRank = pCsr->zRank; const char *zRankArgs = pCsr->zRankArgs; nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); nByte = SZ_FTS5SORTER(nPhrase); pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte); if( pSorter==0 ) return SQLITE_NOMEM; memset(pSorter, 0, (size_t)nByte); pSorter->nIdx = nPhrase; /* TODO: It would be better to have some system for reusing statement ** handles here, rather than preparing a new one for each query. But that |
︙ | ︙ | |||
255959 255960 255961 255962 255963 255964 255965 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); | | | 257266 257267 257268 257269 257270 257271 257272 257273 257274 257275 257276 257277 257278 257279 257280 | static void fts5SourceIdFunc( sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); sqlite3_result_text(pCtx, "fts5: 2025-05-06 17:56:32 6eb2939a6093c0796910645172d80c53055559dd57c012f1dc815d89fbf84447", -1, SQLITE_TRANSIENT); } /* ** Implementation of fts5_locale(LOCALE, TEXT) function. ** ** If parameter LOCALE is NULL, or a zero-length string, then a copy of ** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as |
︙ | ︙ | |||
256184 256185 256186 256187 256188 256189 256190 | } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file ** fts5_test_mi.c is compiled and linked into the executable. And call ** its entry point to enable the matchinfo() demo. */ #ifdef SQLITE_FTS5_ENABLE_TEST_MI if( rc==SQLITE_OK ){ | | | | 257491 257492 257493 257494 257495 257496 257497 257498 257499 257500 257501 257502 257503 257504 257505 257506 | } /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file ** fts5_test_mi.c is compiled and linked into the executable. And call ** its entry point to enable the matchinfo() demo. */ #ifdef SQLITE_FTS5_ENABLE_TEST_MI if( rc==SQLITE_OK ){ extern int sqlite3Fts5TestRegisterMatchinfoAPI(fts5_api*); rc = sqlite3Fts5TestRegisterMatchinfoAPI(&pGlobal->api); } #endif return rc; } /* |
︙ | ︙ | |||
260023 260024 260025 260026 260027 260028 260029 | aAscii[i] = (u8)bToken; } iTbl++; } aAscii[0] = 0; /* 0x00 is never a token character */ } | < | 261330 261331 261332 261333 261334 261335 261336 261337 261338 261339 261340 261341 261342 261343 | aAscii[i] = (u8)bToken; } iTbl++; } aAscii[0] = 0; /* 0x00 is never a token character */ } /* ** 2015 May 30 ** ** 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. |
︙ | ︙ | |||
261616 261617 261618 261619 261620 261621 261622 | (defined(__APPLE__) && defined(__POWERPC__)) || \ (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else # define SQLITE_PTRSIZE 8 # endif # endif /* SQLITE_PTRSIZE */ | | > > | 262922 262923 262924 262925 262926 262927 262928 262929 262930 262931 262932 262933 262934 262935 262936 262937 262938 | (defined(__APPLE__) && defined(__POWERPC__)) || \ (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else # define SQLITE_PTRSIZE 8 # endif # endif /* SQLITE_PTRSIZE */ # if defined(HAVE_STDINT_H) || (defined(__STDC_VERSION__) && \ (__STDC_VERSION__ >= 199901L)) # include <stdint.h> typedef uintptr_t uptr; # elif SQLITE_PTRSIZE==4 typedef unsigned int uptr; # else typedef sqlite3_uint64 uptr; # endif #endif |
︙ | ︙ | |||
262772 262773 262774 262775 262776 262777 262778 262779 262780 262781 262782 262783 262784 262785 | }else{ rc = 999; } return rc; } #endif /* SQLITE_OMIT_AUTHORIZATION */ /* ** This routine reads a line of text from FILE in, stores ** the text in memory obtained from malloc() and returns a pointer ** to the text. NULL is returned at end of file, or if malloc() ** fails. ** ** The interface is like "readline" but no command-line editing | > | 264080 264081 264082 264083 264084 264085 264086 264087 264088 264089 264090 264091 264092 264093 264094 | }else{ rc = 999; } return rc; } #endif /* SQLITE_OMIT_AUTHORIZATION */ #if 0 /* ** This routine reads a line of text from FILE in, stores ** the text in memory obtained from malloc() and returns a pointer ** to the text. NULL is returned at end of file, or if malloc() ** fails. ** ** The interface is like "readline" but no command-line editing |
︙ | ︙ | |||
262816 262817 262818 262819 262820 262821 262822 262823 262824 262825 262826 262827 262828 262829 | zLine[n] = 0; break; } } zLine = realloc( zLine, n+1 ); return zLine; } /* ** This function is part of the implementation of the command: ** ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT ** | > | 264125 264126 264127 264128 264129 264130 264131 264132 264133 264134 264135 264136 264137 264138 264139 | zLine[n] = 0; break; } } zLine = realloc( zLine, n+1 ); return zLine; } #endif /* ** This function is part of the implementation of the command: ** ** $db transaction [-deferred|-immediate|-exclusive] SCRIPT ** |
︙ | ︙ | |||
263597 263598 263599 263600 263601 263602 263603 | ** ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...) ** (2) First descriptive name (depends on authorization type) ** (3) Second descriptive name ** (4) Name of the database (ex: "main", "temp") ** (5) Name of trigger that is doing the access ** | | | 264907 264908 264909 264910 264911 264912 264913 264914 264915 264916 264917 264918 264919 264920 264921 | ** ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...) ** (2) First descriptive name (depends on authorization type) ** (3) Second descriptive name ** (4) Name of the database (ex: "main", "temp") ** (5) Name of trigger that is doing the access ** ** The callback should return one of the following strings: SQLITE_OK, ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. ** ** If this method is invoked with no arguments, the current authorization ** callback string is returned. */ case DB_AUTHORIZER: { #ifdef SQLITE_OMIT_AUTHORIZATION |
︙ | ︙ | |||
264060 264061 264062 264063 264064 264065 264066 | int i, j; /* Loop counters */ int nSep; /* Number of bytes in zSep[] */ int nNull; /* Number of bytes in zNull[] */ char *zSql; /* An SQL statement */ char *zLine; /* A single line of input from the file */ char **azCol; /* zLine[] broken up into columns */ const char *zCommit; /* How to commit changes */ | | > | 265370 265371 265372 265373 265374 265375 265376 265377 265378 265379 265380 265381 265382 265383 265384 265385 265386 265387 | int i, j; /* Loop counters */ int nSep; /* Number of bytes in zSep[] */ int nNull; /* Number of bytes in zNull[] */ char *zSql; /* An SQL statement */ char *zLine; /* A single line of input from the file */ char **azCol; /* zLine[] broken up into columns */ const char *zCommit; /* How to commit changes */ Tcl_Channel in; /* The input file */ int lineno = 0; /* Line number of input file */ char zLineNum[80]; /* Line number print buffer */ Tcl_Obj *str; Tcl_Obj *pResult; /* interp result */ const char *zSep; const char *zNull; if( objc<5 || objc>7 ){ Tcl_WrongNumArgs(interp, 2, objv, "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); |
︙ | ︙ | |||
264141 264142 264143 264144 264145 264146 264147 | rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); free(zSql); if( rc ){ Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); sqlite3_finalize(pStmt); return TCL_ERROR; } | | < > | > > | > > | 265452 265453 265454 265455 265456 265457 265458 265459 265460 265461 265462 265463 265464 265465 265466 265467 265468 265469 265470 265471 265472 265473 265474 265475 265476 265477 265478 265479 265480 265481 265482 265483 265484 265485 265486 | rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); free(zSql); if( rc ){ Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0); sqlite3_finalize(pStmt); return TCL_ERROR; } in = Tcl_OpenFileChannel(interp, zFile, "rb", 0666); if( in==0 ){ sqlite3_finalize(pStmt); return TCL_ERROR; } Tcl_SetChannelOption(NULL, in, "-translation", "auto"); azCol = malloc( sizeof(azCol[0])*(nCol+1) ); if( azCol==0 ) { Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0); Tcl_Close(interp, in); return TCL_ERROR; } str = Tcl_NewObj(); Tcl_IncrRefCount(str); (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0); zCommit = "COMMIT"; while( Tcl_GetsObj(in, str)>=0 ) { char *z; Tcl_Size byteLen; lineno++; zLine = (char *)Tcl_GetByteArrayFromObj(str, &byteLen); azCol[0] = zLine; for(i=0, z=zLine; *z; z++){ if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ *z = 0; i++; if( i<nCol ){ azCol[i] = &z[nSep]; |
︙ | ︙ | |||
264195 264196 264197 264198 264199 264200 264201 | sqlite3_bind_null(pStmt, i+1); }else{ sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); } } sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); | | > | | 265510 265511 265512 265513 265514 265515 265516 265517 265518 265519 265520 265521 265522 265523 265524 265525 265526 265527 265528 265529 265530 265531 265532 265533 | sqlite3_bind_null(pStmt, i+1); }else{ sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); } } sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); Tcl_SetObjLength(str, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0); zCommit = "ROLLBACK"; break; } } Tcl_DecrRefCount(str); free(azCol); Tcl_Close(interp, in); sqlite3_finalize(pStmt); (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0); if( zCommit[0] == 'C' ){ /* success, set result as number of lines processed */ pResult = Tcl_GetObjResult(interp); Tcl_SetIntObj(pResult, lineno); |
︙ | ︙ |