updated vendor

This commit is contained in:
2026-06-16 08:02:19 +02:00
parent 2f7f99d3f0
commit 77299d0c64
1283 changed files with 67302 additions and 208958 deletions
+2
View File
@@ -125,6 +125,7 @@ Boolean values can be one of:
| Transaction Lock | `_txlock` | <ul><li>immediate</li><li>deferred</li><li>exclusive</li></ul> | Specify locking behavior for transactions. |
| Writable Schema | `_writable_schema` | `Boolean` | When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file. |
| Cache Size | `_cache_size` | `int` | Maximum cache size; default is 2000K (2M). See [PRAGMA cache_size](https://sqlite.org/pragma.html#pragma_cache_size) |
| Statement Cache Size | `_stmt_cache_size` | `int` | Maximum number of prepared statements cached per connection; default is 0 (disabled). Note that `sql.DB` is a connection pool, so each connection maintains its own independent cache. |
## DSN Examples
@@ -181,6 +182,7 @@ go build -tags "icu json1 fts5 secure_delete"
| Tracing / Debug | sqlite_trace | Activate trace functions |
| User Authentication | sqlite_userauth | SQLite User Authentication see [User Authentication](#user-authentication) for more information. |
| Virtual Tables | sqlite_vtable | SQLite Virtual Tables see [SQLite Official VTABLE Documentation](https://www.sqlite.org/vtab.html) for more information, and a [full example here](https://github.com/mattn/go-sqlite3/tree/master/_example/vtable) |
| The DBSTAT Virtual Table | sqlite_dbstat | The DBSTAT virtual table is a read-only virtual table that returns information about the amount of disk space used to store the content of an SQLite database. See [SQLite Official Documentation](https://www.sqlite.org/dbstat.html) for more information. |
# Compilation
+33
View File
@@ -0,0 +1,33 @@
# Security Policy
## Supported Versions
Only the latest release on the `v1.14.x` line receives security fixes.
| Version | Supported |
| -------- | ------------------ |
| 1.14.x | :white_check_mark: |
| < 1.14 | :x: |
## Scope
`go-sqlite3` is a CGo binding that bundles the SQLite amalgamation
(`sqlite3-binding.c` / `sqlite3-binding.h`). Please report issues to the
appropriate project:
- Bugs in the Go binding layer, CGo glue, build tags, or this repository's
own code: report here.
- Vulnerabilities in SQLite itself: please report them upstream to the
SQLite developers at <https://www.sqlite.org/>. Once a fix is released
upstream, this repository will update the bundled amalgamation.
## Reporting a Vulnerability
Please **do not** open a public GitHub issue for security problems.
Use GitHub's private vulnerability reporting:
<https://github.com/mattn/go-sqlite3/security/advisories/new>
This project is maintained on a best-effort basis by volunteers, so please
allow reasonable time for investigation and a fix before any public
d
+7691 -4292
View File
File diff suppressed because it is too large Load Diff
+481 -102
View File
@@ -147,12 +147,12 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.51.3"
#define SQLITE_VERSION_NUMBER 3051003
#define SQLITE_SOURCE_ID "2026-03-13 10:38:09 737ae4a34738ffa0c3ff7f9bb18df914dd1cad163f28fd6b6e114a344fe6d618"
#define SQLITE_SCM_BRANCH "branch-3.51"
#define SQLITE_SCM_TAGS "release version-3.51.3"
#define SQLITE_SCM_DATETIME "2026-03-13T10:38:09.694Z"
#define SQLITE_VERSION "3.53.2"
#define SQLITE_VERSION_NUMBER 3053002
#define SQLITE_SOURCE_ID "2026-06-03 19:12:13 d6e03d8c777cfa2d35e3b60d8ec3e0187f3e9f99d8e2ee9cac695fd6fcdf1a24"
#define SQLITE_SCM_BRANCH "branch-3.53"
#define SQLITE_SCM_TAGS "release version-3.53.2"
#define SQLITE_SCM_DATETIME "2026-06-03T19:12:13.350Z"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -579,7 +579,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */
#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal only */
/*
** CAPI3REF: Flags For File Open Operations
@@ -1291,6 +1291,12 @@ struct sqlite3_io_methods {
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
/* reserved file-control numbers:
** 101
** 102
** 103
*/
/*
** CAPI3REF: Mutex Handle
@@ -1491,7 +1497,7 @@ typedef const char *sqlite3_filename;
** greater and the function pointer is not NULL) and will fall back
** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
**
** ^The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces
** ^The xSetSystemCall(), xGetSystemCall(), and xNextSystemCall() interfaces
** are not used by the SQLite core. These optional interfaces are provided
** by some VFSes to facilitate testing of the VFS code. By overriding
** system calls with functions under its control, a test program can
@@ -1712,7 +1718,8 @@ SQLITE_API int sqlite3_os_end(void);
** are called "anytime configuration options".
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
** [sqlite3_shutdown()] with a first argument that is not an anytime
** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE.
** configuration option, then the sqlite3_config() call will
** return SQLITE_MISUSE.
** Note, however, that ^sqlite3_config() can be called as part of the
** implementation of an application-defined [sqlite3_os_init()].
**
@@ -2278,9 +2285,10 @@ struct sqlite3_mem_methods {
** is less than 8. The "sz" argument should be a multiple of 8 less than
** 65536. If "sz" does not meet this constraint, it is reduced in size until
** it does.
** <li><p>The third argument ("cnt") is the number of slots. Lookaside is disabled
** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so
** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt"
** <li><p>The third argument ("cnt") is the number of slots.
** Lookaside is disabled if "cnt"is less than 1.
* The "cnt" value will be reduced, if necessary, so
** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt"
** parameter is usually chosen so that the product of "sz" and "cnt" is less
** than 1,000,000.
** </ol>
@@ -2568,12 +2576,15 @@ struct sqlite3_mem_methods {
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
** statistics. For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is prepared and when it
** is stepped. The flag is set (collection of statistics is enabled)
** by default. <p>This option takes two arguments: an integer and a pointer to
** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears
** a flag that enables collection of run-time performance statistics
** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle]
** columns of the [bytecode virtual table].
** For statistics to be collected, the flag must be set on
** the database handle both when the SQL statement is
** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped].
** The flag is set (collection of statistics is enabled) by default.
** <p>This option takes two arguments: an integer and a pointer to
** an integer. The first argument is 1, 0, or -1 to enable, disable, or
** leave unchanged the statement scanstatus option. If the second argument
** is not NULL, then the value of the statement scanstatus setting after
@@ -2646,16 +2657,34 @@ struct sqlite3_mem_methods {
** comments are allowed in SQL text after processing the first argument.
** </dd>
**
** [[SQLITE_DBCONFIG_FP_DIGITS]]
** <dt>SQLITE_DBCONFIG_FP_DIGITS</dt>
** <dd>The SQLITE_DBCONFIG_FP_DIGITS setting is a small integer that determines
** the number of significant digits that SQLite will attempt to preserve when
** converting floating point numbers (IEEE 754 "doubles") into text. The
** default value 17, as of SQLite version 3.52.0. The value was 15 in all
** prior versions.<p>
** This option takes two arguments which are an integer and a pointer
** to an integer. The first argument is a small integer, between 3 and 23, or
** zero. The FP_DIGITS setting is changed to that small integer, or left
** unaltered if the first argument is zero or out of range. The second argument
** is a pointer to an integer. If the pointer is not NULL, then the value of
** the FP_DIGITS setting, after possibly being modified by the first
** arguments, is written into the integer to which the second argument points.
** </dd>
**
** </dl>
**
** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3>
**
** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the
** overall call to [sqlite3_db_config()] has a total of four parameters.
** The first argument (the third parameter to sqlite3_db_config()) is an integer.
** The second argument is a pointer to an integer. If the first argument is 1,
** then the option becomes enabled. If the first integer argument is 0, then the
** option is disabled. If the first argument is -1, then the option setting
** The first argument (the third parameter to sqlite3_db_config()) is
** an integer.
** The second argument is a pointer to an integer. If the first argument is 1,
** then the option becomes enabled. If the first integer argument is 0,
** then the option is disabled.
** If the first argument is -1, then the option setting
** is unchanged. The second argument, the pointer to an integer, may be NULL.
** If the second argument is not NULL, then a value of 0 or 1 is written into
** the integer to which the second argument points, depending on whether the
@@ -2663,9 +2692,10 @@ struct sqlite3_mem_methods {
** the first argument.
**
** <p>While most SQLITE_DBCONFIG options use the argument format
** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME]
** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the
** documentation of those exceptional options for details.
** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME],
** [SQLITE_DBCONFIG_LOOKASIDE], and [SQLITE_DBCONFIG_FP_DIGITS] options
** are different. See the documentation of those exceptional options for
** details.
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -2690,7 +2720,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */
#define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */
#define SQLITE_DBCONFIG_FP_DIGITS 1023 /* int int* */
#define SQLITE_DBCONFIG_MAX 1023 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -4172,6 +4203,7 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename);
** <li> sqlite3_errmsg()
** <li> sqlite3_errmsg16()
** <li> sqlite3_error_offset()
** <li> sqlite3_db_handle()
** </ul>
**
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
@@ -4218,7 +4250,7 @@ SQLITE_API const char *sqlite3_errstr(int);
SQLITE_API int sqlite3_error_offset(sqlite3 *db);
/*
** CAPI3REF: Set Error Codes And Message
** CAPI3REF: Set Error Code And Message
** METHOD: sqlite3
**
** Set the error code of the database handle passed as the first argument
@@ -4337,6 +4369,10 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt>
** <dd>The maximum depth of the parse tree on any expression.</dd>)^
**
** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt>
** <dd>The maximum depth of the LALR(1) parser stack used to analyze
** input SQL statements.</dd>)^
**
** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt>
** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^
**
@@ -4381,6 +4417,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_VARIABLE_NUMBER 9
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
#define SQLITE_LIMIT_PARSER_DEPTH 12
/*
** CAPI3REF: Prepare Flags
@@ -4425,12 +4462,29 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** fails, the sqlite3_prepare_v3() call returns the same error indications
** with or without this flag; it just omits the call to [sqlite3_log()] that
** logs the error.
**
** [[SQLITE_PREPARE_FROM_DDL]] <dt>SQLITE_PREPARE_FROM_DDL</dt>
** <dd>The SQLITE_PREPARE_FROM_DDL flag causes the SQL compiler to enforce
** security constraints that would otherwise only be enforced when parsing
** the database schema. In other words, the SQLITE_PREPARE_FROM_DDL flag
** causes the SQL compiler to treat the SQL statement being prepared as if
** it had come from an attacker. When SQLITE_PREPARE_FROM_DDL is used and
** [SQLITE_DBCONFIG_TRUSTED_SCHEMA] is off, SQL functions may only be called
** if they are tagged with [SQLITE_INNOCUOUS] and virtual tables may only
** be used if they are tagged with [SQLITE_VTAB_INNOCUOUS]. Best practice
** is to use the SQLITE_PREPARE_FROM_DDL option when preparing any SQL that
** is derived from parts of the database schema. In particular, virtual
** table implementations that run SQL statements that are derived from
** arguments to their CREATE VIRTUAL TABLE statement should always use
** [sqlite3_prepare_v3()] and set the SQLITE_PREPARE_FROM_DDL flag to
** prevent bypass of the [SQLITE_DBCONFIG_TRUSTED_SCHEMA] security checks.
** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT 0x01
#define SQLITE_PREPARE_NORMALIZE 0x02
#define SQLITE_PREPARE_NO_VTAB 0x04
#define SQLITE_PREPARE_DONT_LOG 0x10
#define SQLITE_PREPARE_FROM_DDL 0x20
/*
** CAPI3REF: Compiling An SQL Statement
@@ -4444,8 +4498,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
**
** The preferred routine to use is [sqlite3_prepare_v2()]. The
** [sqlite3_prepare()] interface is legacy and should be avoided.
** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used
** for special purposes.
** [sqlite3_prepare_v3()] has an extra
** [SQLITE_PREPARE_FROM_DDL|"prepFlags" option] that is sometimes
** needed for special purpose or to pass along security restrictions.
**
** The use of the UTF-8 interfaces is preferred, as SQLite currently
** does all parsing using UTF-8. The UTF-16 interfaces are provided
@@ -4850,8 +4905,8 @@ typedef struct sqlite3_context sqlite3_context;
** it should be a pointer to well-formed UTF16 text.
** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
** it should be a pointer to a well-formed unicode string that is
** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
** otherwise.
** either UTF8 if the sixth parameter is SQLITE_UTF8 or SQLITE_UTF8_ZT,
** or UTF16 otherwise.
**
** [[byte-order determination rules]] ^The byte-order of
** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
@@ -4897,10 +4952,15 @@ typedef struct sqlite3_context sqlite3_context;
** object and pointer to it must remain valid until then. ^SQLite will then
** manage the lifetime of its private copy.
**
** ^The sixth argument to sqlite3_bind_text64() must be one of
** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
** to specify the encoding of the text in the third parameter. If
** the sixth argument to sqlite3_bind_text64() is not one of the
** ^The sixth argument (the E argument)
** to sqlite3_bind_text64(S,K,Z,N,D,E) must be one of
** [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE],
** or [SQLITE_UTF16LE] to specify the encoding of the text in the
** third parameter, Z. The special value [SQLITE_UTF8_ZT] means that the
** string argument is both UTF-8 encoded and is zero-terminated. In other
** words, SQLITE_UTF8_ZT means that the Z array is allocated to hold at
** least N+1 bytes and that the Z&#91;N&#93; byte is zero. If
** the E argument to sqlite3_bind_text64(S,K,Z,N,D,E) is not one of the
** allowed values shown above, or if the text encoding is different
** from the encoding specified by the sixth parameter, then the behavior
** is undefined.
@@ -5767,6 +5827,52 @@ SQLITE_API int sqlite3_create_window_function(
**
** These constants define integer codes that represent the various
** text encodings supported by SQLite.
**
** <dl>
** [[SQLITE_UTF8]] <dt>SQLITE_UTF8</dt><dd>Text is encoding as UTF-8</dd>
**
** [[SQLITE_UTF16LE]] <dt>SQLITE_UTF16LE</dt><dd>Text is encoding as UTF-16
** with each code point being expressed "little endian" - the least significant
** byte first. This is the usual encoding, for example on Windows.</dd>
**
** [[SQLITE_UTF16BE]] <dt>SQLITE_UTF16BE</dt><dd>Text is encoding as UTF-16
** with each code point being expressed "big endian" - the most significant
** byte first. This encoding is less common, but is still sometimes seen,
** specially on older systems.
**
** [[SQLITE_UTF16]] <dt>SQLITE_UTF16</dt><dd>Text is encoding as UTF-16
** with each code point being expressed either little endian or as big
** endian, according to the native endianness of the host computer.
**
** [[SQLITE_ANY]] <dt>SQLITE_ANY</dt><dd>This encoding value may only be used
** to declare the preferred text for [application-defined SQL functions]
** created using [sqlite3_create_function()] and similar. If the preferred
** encoding (the 4th parameter to sqlite3_create_function() - the eTextRep
** parameter) is SQLITE_ANY, that indicates that the function does not have
** a preference regarding the text encoding of its parameters and can take
** any text encoding that the SQLite core find convenient to supply. This
** option is deprecated. Please do not use it in new applications.
**
** [[SQLITE_UTF16_ALIGNED]] <dt>SQLITE_UTF16_ALIGNED</dt><dd>This encoding
** value may be used as the 3rd parameter (the eTextRep parameter) to
** [sqlite3_create_collation()] and similar. This encoding value means
** that the application-defined collating sequence created expects its
** input strings to be in UTF16 in native byte order, and that the start
** of the strings must be aligned to a 2-byte boundary.
**
** [[SQLITE_UTF8_ZT]] <dt>SQLITE_UTF8_ZT</dt><dd>This option can only be
** used to specify the text encoding to strings input to
** [sqlite3_result_text64()] and [sqlite3_bind_text64()].
** The SQLITE_UTF8_ZT encoding means that the input string (call it "z")
** is UTF-8 encoded and that it is zero-terminated. If the length parameter
** (call it "n") is non-negative, this encoding option means that the caller
** guarantees that z array contains at least n+1 bytes and that the z&#91;n&#93;
** byte has a value of zero.
** This option gives the same output as SQLITE_UTF8, but can be more efficient
** by avoiding the need to make a copy of the input string, in some cases.
** However, if z is allocated to hold fewer than n+1 bytes or if the
** z&#91;n&#93; byte is not zero, undefined behavior may result.
** </dl>
*/
#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */
#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */
@@ -5774,6 +5880,7 @@ SQLITE_API int sqlite3_create_window_function(
#define SQLITE_UTF16 4 /* Use native byte order */
#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
#define SQLITE_UTF8_ZT 16 /* Zero-terminated UTF8 */
/*
** CAPI3REF: Function Flags
@@ -6008,26 +6115,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** the SQL function that supplied the [sqlite3_value*] parameters.
**
** As long as the input parameter is correct, these routines can only
** fail if an out-of-memory error occurs during a format conversion.
** Only the following subset of interfaces are subject to out-of-memory
** errors:
**
** <ul>
** <li> sqlite3_value_blob()
** <li> sqlite3_value_text()
** <li> sqlite3_value_text16()
** <li> sqlite3_value_text16le()
** <li> sqlite3_value_text16be()
** <li> sqlite3_value_bytes()
** <li> sqlite3_value_bytes16()
** </ul>
**
** fail if an out-of-memory error occurs while trying to do a
** UTF8&rarr;UTF16 or UTF16&rarr;UTF8 conversion.
** If an out-of-memory error occurs, then the return value from these
** routines is the same as if the column had contained an SQL NULL value.
** Valid SQL NULL returns can be distinguished from out-of-memory errors
** by invoking the [sqlite3_errcode()] immediately after the suspect
** If the input sqlite3_value was not obtained from [sqlite3_value_dup()],
** then valid SQL NULL returns can also be distinguished from
** out-of-memory errors after extracting the value
** by invoking the [sqlite3_errcode()] immediately after the suspicious
** return value is obtained and before any
** other SQLite interface is called on the same [database connection].
** If the input sqlite3_value was obtained from sqlite3_value_dup() then
** it is disconnected from the database connection and so sqlite3_errcode()
** will not work.
** In that case, the only way to distinguish an out-of-memory
** condition from a true SQL NULL is to invoke sqlite3_value_type() on the
** input to see if it is NULL prior to trying to extract the value.
*/
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
SQLITE_API double sqlite3_value_double(sqlite3_value*);
@@ -6054,7 +6157,8 @@ SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X)
** returns something other than SQLITE_TEXT, then the return value from
** sqlite3_value_encoding(X) is meaningless. ^Calls to
** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)],
** [sqlite3_value_text(X)], [sqlite3_value_text16(X)],
** [sqlite3_value_text16be(X)],
** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or
** [sqlite3_value_bytes16(X)] might change the encoding of the value X and
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
@@ -6185,17 +6289,17 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
** query execution, under some circumstances the associated auxiliary data
** might be preserved. An example of where this might be useful is in a
** regular-expression matching function. The compiled version of the regular
** expression can be stored as auxiliary data associated with the pattern string.
** Then as long as the pattern string remains the same,
** expression can be stored as auxiliary data associated with the pattern
** string. Then as long as the pattern string remains the same,
** the compiled regular expression can be reused on multiple
** invocations of the same function.
**
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data
** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument
** value to the application-defined function. ^N is zero for the left-most
** function argument. ^If there is no auxiliary data
** associated with the function argument, the sqlite3_get_auxdata(C,N) interface
** returns a NULL pointer.
** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary
** data associated by the sqlite3_set_auxdata(C,N,P,X) function with the
** Nth argument value to the application-defined function. ^N is zero
** for the left-most function argument. ^If there is no auxiliary data
** associated with the function argument, the sqlite3_get_auxdata(C,N)
** interface returns a NULL pointer.
**
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the
** N-th argument of the application-defined function. ^Subsequent
@@ -6279,10 +6383,14 @@ SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(voi
**
** There is no limit (other than available memory) on the number of different
** client data pointers (with different names) that can be attached to a
** single database connection. However, the implementation is optimized
** for the case of having only one or two different client data names.
** Applications and wrapper libraries are discouraged from using more than
** one client data name each.
** single database connection. However, the current implementation stores
** the content on a linked list. Insert and retrieval performance will
** be proportional to the number of entries. The design use case, and
** the use case for which the implementation is optimized, is
** that an application will store only small number of client data names,
** typically just one or two. This interface is not intended to be a
** generalized key/value store for thousands or millions of keys. It
** will work for that, but performance might be disappointing.
**
** There is no way to enumerate the client data pointers
** associated with a database connection. The N parameter can be thought
@@ -6390,10 +6498,14 @@ typedef void (*sqlite3_destructor_type)(void*);
** set the return value of the application-defined function to be
** a text string which is represented as UTF-8, UTF-16 native byte order,
** UTF-16 little endian, or UTF-16 big endian, respectively.
** ^The sqlite3_result_text64() interface sets the return value of an
** ^The sqlite3_result_text64(C,Z,N,D,E) interface sets the return value of an
** application-defined function to be a text string in an encoding
** specified by the fifth (and last) parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
** specified the E parameter, which must be one
** of [SQLITE_UTF8], [SQLITE_UTF8_ZT], [SQLITE_UTF16], [SQLITE_UTF16BE],
** or [SQLITE_UTF16LE]. ^The special value [SQLITE_UTF8_ZT] means that
** the result text is both UTF-8 and zero-terminated. In other words,
** SQLITE_UTF8_ZT means that the Z array holds at least N+1 bytes and that
** the Z&#91;N&#93; is zero.
** ^SQLite takes the text result from the application from
** the 2nd parameter of the sqlite3_result_text* interfaces.
** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces
@@ -6480,7 +6592,7 @@ SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
SQLITE_API void sqlite3_result_null(sqlite3_context*);
SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char *z, sqlite3_uint64 n,
void(*)(void*), unsigned char encoding);
SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
@@ -7419,7 +7531,7 @@ SQLITE_API int sqlite3_table_column_metadata(
** ^The sqlite3_load_extension() interface attempts to load an
** [SQLite extension] library contained in the file zFile. If
** the file cannot be loaded directly, attempts are made to load
** with various operating-system specific extensions added.
** with various operating-system specific filename extensions added.
** So for example, if "samplelib" cannot be loaded, then names like
** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
** be tried also.
@@ -7427,10 +7539,10 @@ SQLITE_API int sqlite3_table_column_metadata(
** ^The entry point is zProc.
** ^(zProc may be 0, in which case SQLite will try to come up with an
** entry point name on its own. It first tries "sqlite3_extension_init".
** If that does not work, it constructs a name "sqlite3_X_init" where
** X consists of the lower-case equivalent of all ASCII alphabetic
** characters in the filename from the last "/" to the first following
** "." and omitting any initial "lib".)^
** If that does not work, it tries names of the form "sqlite3_X_init"
** where X consists of the lower-case equivalent of all ASCII alphabetic
** characters or all ASCII alphanumeric characters in the filename from
** the last "/" to the first following "." and omitting any initial "lib".)^
** ^The sqlite3_load_extension() interface returns
** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
** ^If an error occurs and pzErrMsg is not 0, then the
@@ -7504,7 +7616,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** <blockquote><pre>
** &nbsp; int xEntryPoint(
** &nbsp; sqlite3 *db,
** &nbsp; const char **pzErrMsg,
** &nbsp; char **pzErrMsg,
** &nbsp; const struct sqlite3_api_routines *pThunk
** &nbsp; );
** </pre></blockquote>)^
@@ -8254,13 +8366,6 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
** and Windows.
**
** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
** implementation is included with the library. In this case the
** application must supply a custom mutex implementation using the
** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
** before calling sqlite3_initialize() or any other public sqlite3_
** function that calls sqlite3_initialize().
**
** ^The sqlite3_mutex_alloc() routine allocates a new
** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
@@ -8615,6 +8720,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_TUNE 32
#define SQLITE_TESTCTRL_LOGEST 33
#define SQLITE_TESTCTRL_USELONGDOUBLE 34 /* NOT USED */
#define SQLITE_TESTCTRL_ATOF 34
#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */
/*
@@ -8723,17 +8829,22 @@ SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
** pass the returned value to [sqlite3_free()] to avoid a memory leak.
** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
** errors were encountered during construction of the string. ^The
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
** [sqlite3_str_finish(X)] interface might also return a NULL pointer if the
** string in [sqlite3_str] object X is zero bytes long.
**
** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object
** X and the string content it contains. Calling sqlite3_str_free(X) is
** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)).
*/
SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
SQLITE_API void sqlite3_str_free(sqlite3_str*);
/*
** CAPI3REF: Add Content To A Dynamic String
** METHOD: sqlite3_str
**
** These interfaces add content to an sqlite3_str object previously obtained
** from [sqlite3_str_new()].
** These interfaces add or remove content to an sqlite3_str object
** previously obtained from [sqlite3_str_new()].
**
** ^The [sqlite3_str_appendf(X,F,...)] and
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
@@ -8756,6 +8867,10 @@ SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
** ^The [sqlite3_str_reset(X)] method resets the string under construction
** inside [sqlite3_str] object X back to zero bytes in length.
**
** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string
** under construction to be N bytes or less. This routine is a no-op if
** N is negative or if the string is already N bytes or smaller in size.
**
** These methods do not return a result code. ^If an error occurs, that fact
** is recorded in the [sqlite3_str] object and can be recovered by a
** subsequent call to [sqlite3_str_errcode(X)].
@@ -8766,6 +8881,7 @@ SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
SQLITE_API void sqlite3_str_reset(sqlite3_str*);
SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N);
/*
** CAPI3REF: Status Of A Dynamic String
@@ -10296,7 +10412,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
** <tr>
** <td valign="top">sqlite3_vtab_distinct() return value
** <td valign="top">Rows are returned in aOrderBy order
** <td valign="top">Rows with the same value in all aOrderBy columns are adjacent
** <td valign="top">Rows with the same value in all aOrderBy columns are
** adjacent
** <td valign="top">Duplicates over all colUsed columns may be omitted
** <tr><td>0<td>yes<td>yes<td>no
** <tr><td>1<td>no<td>yes<td>no
@@ -10305,8 +10422,8 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
** </table>
**
** ^For the purposes of comparing virtual table output values to see if the
** values are the same value for sorting purposes, two NULL values are considered
** to be the same. In other words, the comparison operator is "IS"
** values are the same value for sorting purposes, two NULL values are
** considered to be the same. In other words, the comparison operator is "IS"
** (or "IS NOT DISTINCT FROM") and not "==".
**
** If a virtual table implementation is unable to meet the requirements
@@ -10599,9 +10716,9 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** a variable pointed to by the "pOut" parameter.
**
** The "flags" parameter must be passed a mask of flags. At present only
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX
** is specified, then status information is available for all elements
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
** the EXPLAIN QUERY PLAN output) are available. Invoking API
@@ -10615,7 +10732,8 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** elements used to implement the statement - a non-zero value is returned and
** the variable that pOut points to is unchanged.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
** See also: [sqlite3_stmt_scanstatus_reset()] and the
** [nexec and ncycle] columns of the [bytecode virtual table].
*/
SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
@@ -11157,19 +11275,42 @@ SQLITE_API int sqlite3_deserialize(
/*
** CAPI3REF: Bind array values to the CARRAY table-valued function
**
** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to
** one of the first argument of the [carray() table-valued function]. The
** S parameter is a pointer to the [prepared statement] that uses the carray()
** functions. I is the parameter index to be bound. P is a pointer to the
** array to be bound, and N is the number of eements in the array. The
** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to
** indicate the datatype of the array being bound. The X argument is not a
** NULL pointer, then SQLite will invoke the function X on the P parameter
** after it has finished using P, even if the call to
** sqlite3_carray_bind() fails. The special-case finalizer
** SQLITE_TRANSIENT has no effect here.
** The sqlite3_carray_bind_v2(S,I,P,N,F,X,D) interface binds an array value to
** parameter that is the first argument of the [carray() table-valued function].
** The S parameter is a pointer to the [prepared statement] that uses the
** carray() functions. I is the parameter index to be bound. I must be the
** index of the parameter that is the first argument to the carray()
** table-valued function. P is a pointer to the array to be bound, and N
** is the number of elements in the array. The F argument is one of
** constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64],
** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT],
** or [SQLITE_CARRAY_BLOB] to indicate the datatype of the array P.
**
** If the X argument is not a NULL pointer or one of the special
** values [SQLITE_STATIC] or [SQLITE_TRANSIENT], then SQLite will invoke
** the function X with argument D when it is finished using the data in P.
** The call to X(D) is a destructor for the array P. The destructor X(D)
** is invoked even if the call to sqlite3_carray_bind_v2() fails. If the X
** parameter is the special-case value [SQLITE_STATIC], then SQLite assumes
** that the data static and the destructor is never invoked. If the X
** parameter is the special-case value [SQLITE_TRANSIENT], then
** sqlite3_carray_bind_v2() makes its own private copy of the data prior
** to returning and never invokes the destructor X.
**
** The sqlite3_carray_bind() function works the same as sqlite3_carray_bind_v2()
** with a D parameter set to P. In other words,
** sqlite3_carray_bind(S,I,P,N,F,X) is same as
** sqlite3_carray_bind_v2(S,I,P,N,F,X,P).
*/
SQLITE_API int sqlite3_carray_bind_v2(
sqlite3_stmt *pStmt, /* Statement to be bound */
int i, /* Parameter index */
void *aData, /* Pointer to array data */
int nData, /* Number of data elements */
int mFlags, /* CARRAY flags */
void (*xDel)(void*), /* Destructor for aData */
void *pDel /* Optional argument to xDel() */
);
SQLITE_API int sqlite3_carray_bind(
sqlite3_stmt *pStmt, /* Statement to be bound */
int i, /* Parameter index */
@@ -12713,11 +12854,23 @@ SQLITE_API int sqlite3changeset_apply_v3(
** database behave as if they were declared with "ON UPDATE NO ACTION ON
** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL
** or SET DEFAULT.
**
** <dt>SQLITE_CHANGESETAPPLY_NOUPDATELOOP <dd>
** Sometimes, a changeset contains two or more update statements such that
** although after applying all updates the database will contain no
** constraint violations, no single update can be applied before the others.
** The simplest example of this is a pair of UPDATEs that have "swapped"
** two column values with a UNIQUE constraint.
** <p>
** Usually, sqlite3changeset_apply() and similar functions work hard to try
** to find a way to apply such a changeset. However, if this flag is set,
** then all such updates are considered CONSTRAINT conflicts.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008
#define SQLITE_CHANGESETAPPLY_NOUPDATELOOP 0x0010
/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -13200,6 +13353,232 @@ SQLITE_API int sqlite3session_config(int op, void *pArg);
*/
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
** CAPI3REF: Configure a changegroup object
**
** Configure the changegroup object passed as the first argument.
** At present the only valid value for the second parameter is
** [SQLITE_CHANGEGROUP_CONFIG_PATCHSET].
*/
SQLITE_API int sqlite3changegroup_config(sqlite3_changegroup*, int, void *pArg);
/*
** CAPI3REF: Options for sqlite3changegroup_config().
**
** The following values may be passed as the 2nd parameter to
** sqlite3changegroup_config().
**
** <dt>SQLITE_CHANGEGROUP_CONFIG_PATCHSET <dd>
** A changegroup object generates either a changeset or patchset. Usually,
** this is determined by whether the first call to sqlite3changegroup_add()
** is passed a changeset or a patchset. Or, if the first changes are added
** to the changegroup object using the sqlite3changegroup_change_xxx()
** APIs, then this option may be used to configure whether the changegroup
** object generates a changeset or patchset.
**
** When this option is invoked, parameter pArg must point to a value of
** type int. If the changegroup currently contains zero changes, and the
** value of the int variable is zero or greater than zero, then the
** changegroup is configured to generate a changeset or patchset,
** respectively. It is a no-op, not an error, if the changegroup is not
** configured because it has already started accumulating changes.
**
** Before returning, the int variable is set to 0 if the changegroup is
** configured to generate a changeset, or 1 if it is configured to generate
** a patchset.
*/
#define SQLITE_CHANGEGROUP_CONFIG_PATCHSET 1
/*
** CAPI3REF: Begin adding a change to a changegroup
**
** This API is used, in concert with other sqlite3changegroup_change_xxx()
** APIs, to add changes to a changegroup object one at a time. To add a
** single change, the caller must:
**
** 1. Invoke sqlite3changegroup_change_begin() to indicate the type of
** change (INSERT, UPDATE or DELETE), the affected table and whether
** or not the change should be marked as indirect.
**
** 2. Invoke sqlite3changegroup_change_int64() or one of the other four
** value functions - _null(), _double(), _text() or _blob() - one or
** more times to specify old.* and new.* values for the change being
** constructed.
**
** 3. Invoke sqlite3changegroup_change_finish() to either finish adding
** the change to the group, or to discard the change altogether.
**
** The first argument to this function must be a pointer to the existing
** changegroup object that the change will be added to. The second argument
** must be SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE. The third is the
** name of the table that the change affects, and the fourth is a boolean
** flag specifying whether the change should be marked as "indirect" (if
** bIndirect is non-zero) or not indirect (if bIndirect is zero).
**
** Following a successful call to this function, this function may not be
** called again on the same changegroup object until after
** sqlite3changegroup_change_finish() has been called. Doing so is an
** SQLITE_MISUSE error.
**
** The changegroup object passed as the first argument must be already
** configured with schema data for the specified table. It may be configured
** either by calling sqlite3changegroup_schema() with a database that contains
** the table, or sqlite3changegroup_add() with a changeset that contains the
** table. If the changegroup object has not been configured with a schema for
** the specified table when this function is called, SQLITE_ERROR is returned.
**
** If successful, SQLITE_OK is returned. Otherwise, if an error occurs, an
** SQLite error code is returned. In this case, if argument pzErr is non-NULL,
** then (*pzErr) may be set to point to a buffer containing a utf-8 formated,
** nul-terminated, English language error message. It is the responsibility
** of the caller to eventually free this buffer using sqlite3_free().
*/
SQLITE_API int sqlite3changegroup_change_begin(
sqlite3_changegroup*,
int eOp,
const char *zTab,
int bIndirect,
char **pzErr
);
/*
** CAPI3REF: Add a 64-bit integer to a changegroup
**
** This function may only be called between a successful call to
** sqlite3changegroup_change_begin() and its matching
** sqlite3changegroup_change_finish() call. If it is called at any
** other time, it is an SQLITE_MISUSE error. Calling this function
** specifies a 64-bit integer value to be used in the change currently being
** added to the changegroup object passed as the first argument.
**
** The second parameter, bNew, specifies whether the value is to be part of
** the new.* (if bNew is non-zero) or old.* (if bNew is zero) record of
** the change under construction. If this does not match the type of change
** specified by the preceding call to sqlite3changegroup_change_begin() (i.e.
** an old.* value for an SQLITE_INSERT change, or a new.* value for an
** SQLITE_DELETE), then SQLITE_ERROR is returned.
**
** The third parameter specifies the column of the old.* or new.* record that
** the value will be a part of. If the specified table has an explicit primary
** key, then this is the index of the table column, numbered from 0 in the order
** specified within the CREATE TABLE statement. Or, if the table uses an
** implicit rowid key, then the column 0 is the rowid and the explicit columns
** are numbered starting from 1. If the iCol parameter is less than 0 or greater
** than the index of the last column in the table, SQLITE_RANGE is returned.
**
** The fourth parameter is the integer value to use as part of the old.* or
** new.* record.
**
** If this call is successful, SQLITE_OK is returned. Otherwise, if an
** error occurs, an SQLite error code is returned.
*/
SQLITE_API int sqlite3changegroup_change_int64(
sqlite3_changegroup*,
int bNew,
int iCol,
sqlite3_int64 iVal
);
/*
** CAPI3REF: Add a NULL to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). Except that
** it configures the change currently under construction with a NULL value
** instead of a 64-bit integer.
*/
SQLITE_API int sqlite3changegroup_change_null(sqlite3_changegroup*, int, int);
/*
** CAPI3REF: Add an double to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). Except that
** it configures the change currently being constructed with a real value
** instead of a 64-bit integer.
*/
SQLITE_API int sqlite3changegroup_change_double(sqlite3_changegroup*, int, int, double);
/*
** CAPI3REF: Add a text value to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). It configures
** the currently accumulated change with a text value instead of a 64-bit
** integer. Parameter pVal points to a buffer containing the text encoded using
** utf-8. Parameter nVal may either be the size of the text value in bytes, or
** else a negative value, in which case the buffer pVal points to is assumed to
** be nul-terminated.
*/
SQLITE_API int sqlite3changegroup_change_text(
sqlite3_changegroup*, int, int, const char *pVal, int nVal
);
/*
** CAPI3REF: Add a blob to a changegroup
**
** This function is similar to sqlite3changegroup_change_int64(). It configures
** the currently accumulated change with a blob value instead of a 64-bit
** integer. Parameter pVal points to a buffer containing the blob. Parameter
** nVal is the size of the blob in bytes.
*/
SQLITE_API int sqlite3changegroup_change_blob(
sqlite3_changegroup*, int, int, const void *pVal, int nVal
);
/*
** CAPI3REF: Finish adding one-at-at-time changes to a changegroup
**
** This function may only be called following a successful call to
** sqlite3changegroup_change_begin(). Otherwise, it is an SQLITE_MISUSE error.
**
** If parameter bDiscard is non-zero, then the current change is simply
** discarded. In this case this function is always successful and SQLITE_OK
** returned.
**
** If parameter bDiscard is zero, then an attempt is made to add the current
** change to the changegroup. Assuming the changegroup is configured to
** produce a changeset (not a patchset), this requires that:
**
** * If the change is an INSERT or DELETE, then a value must be specified
** for all columns of the new.* or old.* record, respectively.
**
** * If the change is an UPDATE record, then values must be provided for
** the PRIMARY KEY columns of the old.* record, but must not be provided
** for PRIMARY KEY columns of the new.* record.
**
** * If the change is an UPDATE record, then for each non-PRIMARY KEY
** column in the old.* record for which a value has been provided, a
** value must also be provided for the same column in the new.* record.
** Similarly, for each non-PK column in the old.* record for which
** a value is not provided, a value must not be provided for the same
** column in the new.* record.
**
** * All values specified for PRIMARY KEY columns must be non-NULL.
**
** Otherwise, it is an error.
**
** If the changegroup already contains a change for the same row (identified
** by PRIMARY KEY columns), then the current change is combined with the
** existing change in the same way as for sqlite3changegroup_add().
**
** For a patchset, all of the above rules apply except that it doesn't matter
** whether or not values are provided for the non-PK old.* record columns
** for an UPDATE or DELETE change. This means that code used to produce
** a changeset using the sqlite3changegroup_change_xxx() APIs may also
** be used to produce patchsets.
**
** If the call is successful, SQLITE_OK is returned. Otherwise, if an error
** occurs, an SQLite error code is returned. If an error is returned and
** parameter pzErr is not NULL, then (*pzErr) may be set to point to a buffer
** containing a nul-terminated, utf-8 encoded, English language error message.
** It is the responsibility of the caller to eventually free any such error
** message buffer using sqlite3_free().
*/
SQLITE_API int sqlite3changegroup_change_finish(
sqlite3_changegroup*,
int bDiscard,
char **pzErr
);
/*
** Make sure we can call this stuff from C++.
*/
+481 -163
View File
@@ -69,13 +69,49 @@ _sqlite3_open_v2(const char *filename, sqlite3 **ppDb, int flags, const char *zV
}
static int
_sqlite3_bind_text(sqlite3_stmt *stmt, int n, char *p, int np) {
return sqlite3_bind_text(stmt, n, p, np, SQLITE_TRANSIENT);
_sqlite3_bind_text(sqlite3_stmt *stmt, int n, char *p, sqlite3_uint64 np) {
return sqlite3_bind_text64(stmt, n, p, np, SQLITE_TRANSIENT, SQLITE_UTF8);
}
static int
_sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
return sqlite3_bind_blob(stmt, n, p, np, SQLITE_TRANSIENT);
_sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, sqlite3_uint64 np) {
return sqlite3_bind_blob64(stmt, n, p, np, SQLITE_TRANSIENT);
}
typedef struct {
int typ;
sqlite3_int64 i64;
double f64;
const void *ptr;
int n;
} sqlite3_go_col;
static void
_sqlite3_column_values(sqlite3_stmt *stmt, int ncol, sqlite3_go_col *cols) {
for (int i = 0; i < ncol; i++) {
sqlite3_go_col *col = &cols[i];
col->typ = sqlite3_column_type(stmt, i);
col->ptr = 0;
col->n = 0;
switch (col->typ) {
case SQLITE_INTEGER:
col->i64 = sqlite3_column_int64(stmt, i);
break;
case SQLITE_FLOAT:
col->f64 = sqlite3_column_double(stmt, i);
break;
case SQLITE_BLOB:
col->ptr = sqlite3_column_blob(stmt, i);
col->n = sqlite3_column_bytes(stmt, i);
break;
case SQLITE_TEXT:
col->ptr = sqlite3_column_text(stmt, i);
col->n = sqlite3_column_bytes(stmt, i);
break;
default:
break;
}
}
}
#include <stdio.h>
@@ -90,10 +126,57 @@ _sqlite3_exec(sqlite3* db, const char* pcmd, long long* rowid, long long* change
return rv;
}
// Combined reset + clear_bindings in a single C call to reduce CGO crossings.
static int
_sqlite3_reset_clear(sqlite3_stmt* stmt)
{
int rv = sqlite3_reset(stmt);
sqlite3_clear_bindings(stmt);
return rv;
}
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
extern int _sqlite3_step_blocking(sqlite3_stmt *stmt);
extern int _sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes);
extern int _sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail);
#endif
// Combined prepare+step+finalize for simple exec without parameters.
// Reduces CGO crossings from ~6 to 1 for the common no-args exec case.
static int
_sqlite3_exec_no_args(sqlite3* db, const char* zSql, int nBytes, long long* rowid, long long* changes, const char** pzTail)
{
sqlite3_stmt *stmt = 0;
const char *tail = 0;
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
int rv = _sqlite3_prepare_v2_blocking(db, zSql, nBytes, &stmt, &tail);
#else
int rv = sqlite3_prepare_v2(db, zSql, nBytes, &stmt, &tail);
#endif
if (rv != SQLITE_OK) {
*pzTail = 0;
return rv;
}
if (stmt == 0) {
// Empty statement
*rowid = 0;
*changes = 0;
*pzTail = tail;
return SQLITE_OK;
}
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
rv = _sqlite3_step_row_blocking(stmt, rowid, changes);
#else
rv = sqlite3_step(stmt);
*rowid = (long long) sqlite3_last_insert_rowid(db);
*changes = (long long) sqlite3_changes(db);
#endif
sqlite3_finalize(stmt);
*pzTail = tail;
return rv;
}
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
static int
_sqlite3_step_internal(sqlite3_stmt *stmt)
@@ -210,6 +293,7 @@ import (
"errors"
"fmt"
"io"
"math"
"net/url"
"reflect"
"runtime"
@@ -361,12 +445,20 @@ type SQLiteDriver struct {
// SQLiteConn implements driver.Conn.
type SQLiteConn struct {
mu sync.Mutex
db *C.sqlite3
loc *time.Location
txlock string
funcs []*functionInfo
aggregators []*aggInfo
mu sync.Mutex
db *C.sqlite3
loc *time.Location
txlock string
funcs []*functionInfo
aggregators []*aggInfo
// Prepared-statement cache. The slice is allocated at Open with a
// fixed capacity equal to the configured cache size; cap bounds the
// cache, len is the live count, and entries are ordered LRU-first
// (index 0 is the oldest, the tail is most recently put). Access
// requires mu; stmtCacheEnabled is immutable after Open and is the
// only field safe to read without the lock.
stmtCache []*SQLiteStmt
stmtCacheEnabled bool
}
// SQLiteTx implements driver.Tx.
@@ -376,12 +468,14 @@ type SQLiteTx struct {
// SQLiteStmt implements driver.Stmt.
type SQLiteStmt struct {
mu sync.Mutex
c *SQLiteConn
s *C.sqlite3_stmt
t string
closed bool
cls bool // True if the statement was created by SQLiteConn.Query
mu sync.Mutex
c *SQLiteConn
s *C.sqlite3_stmt
t string
closed bool
cls bool // True if the statement was created by SQLiteConn.Query
namedParams map[string][3]int
cacheKey string
}
// SQLiteResult implements sql.Result.
@@ -397,6 +491,7 @@ type SQLiteRows struct {
cls bool // True if we need to close the parent statement in Close
cols []string
decltype []string
colvals *C.sqlite3_go_col
ctx context.Context // no better alternative to pass context into Next() method
closemu sync.Mutex
}
@@ -847,45 +942,29 @@ func lastError(db *C.sqlite3) error {
// Exec implements Execer.
func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, error) {
list := make([]driver.NamedValue, len(args))
for i, v := range args {
list[i] = driver.NamedValue{
Ordinal: i + 1,
Value: v,
}
}
return c.exec(context.Background(), query, list)
return c.exec(context.Background(), query, valueToNamedValue(args))
}
func (c *SQLiteConn) exec(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
// Fast path: no args, no context cancellation → single CGO call per statement
if len(args) == 0 && ctx.Done() == nil {
return c.execNoArgs(query)
}
start := 0
for {
s, err := c.prepare(ctx, query)
s, err := c.prepareWithCache(ctx, query)
if err != nil {
return nil, err
}
var res driver.Result
if s.(*SQLiteStmt).s != nil {
stmtArgs := make([]driver.NamedValue, 0, len(args))
na := s.NumInput()
if len(args)-start < na {
s.Close()
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args))
}
// consume the number of arguments used in the current
// statement and append all named arguments not
// contained therein
if na > 0 {
stmtArgs = append(stmtArgs, args[start:start+na]...)
for i := range args {
if (i < start || i >= na) && args[i].Name != "" {
stmtArgs = append(stmtArgs, args[i])
}
}
for i := range stmtArgs {
stmtArgs[i].Ordinal = i + 1
}
}
stmtArgs := stmtArgs(args, start, na)
res, err = s.(*SQLiteStmt).exec(ctx, stmtArgs)
if err != nil && err != driver.ErrSkip {
s.Close()
@@ -906,56 +985,74 @@ func (c *SQLiteConn) exec(ctx context.Context, query string, args []driver.Named
}
}
// execNoArgs executes a query with no parameters in a single CGO call per statement.
func (c *SQLiteConn) execNoArgs(query string) (driver.Result, error) {
var res *SQLiteResult
for len(query) > 0 {
var rowid, changes C.longlong
var tail *C.char
pquery := C.CString(query)
rv := C._sqlite3_exec_no_args(c.db, pquery, C.int(len(query)), &rowid, &changes, &tail)
if tail != nil && *tail != '\000' {
query = strings.TrimSpace(C.GoString(tail))
} else {
query = ""
}
C.free(unsafe.Pointer(pquery))
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
return nil, c.lastError()
}
res = &SQLiteResult{id: int64(rowid), changes: int64(changes)}
}
if res == nil {
res = &SQLiteResult{0, 0}
}
return res, nil
}
// Query implements Queryer.
func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, error) {
list := make([]driver.NamedValue, len(args))
for i, v := range args {
list[i] = driver.NamedValue{
Ordinal: i + 1,
Value: v,
}
}
return c.query(context.Background(), query, list)
return c.query(context.Background(), query, valueToNamedValue(args))
}
func (c *SQLiteConn) query(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
start := 0
for {
stmtArgs := make([]driver.NamedValue, 0, len(args))
s, err := c.prepare(ctx, query)
s, err := c.prepareWithCache(ctx, query)
if err != nil {
return nil, err
}
s.(*SQLiteStmt).cls = true
ss := s.(*SQLiteStmt)
ss.cls = true
// sqlite3_prepare_v2 returns SQLITE_OK with a NULL statement handle
// when the input is empty or contains only whitespace/comments.
if ss.s == nil {
tail := ss.t
ss.Close()
if tail == "" {
return &SQLiteRows{cls: true, ctx: ctx}, nil
}
query = tail
continue
}
na := s.NumInput()
if len(args)-start < na {
s.Close()
ss.Close()
return nil, fmt.Errorf("not enough args to execute query: want %d got %d", na, len(args)-start)
}
// consume the number of arguments used in the current
// statement and append all named arguments not contained
// therein
stmtArgs = append(stmtArgs, args[start:start+na]...)
for i := range args {
if (i < start || i >= na) && args[i].Name != "" {
stmtArgs = append(stmtArgs, args[i])
}
}
for i := range stmtArgs {
stmtArgs[i].Ordinal = i + 1
}
rows, err := s.(*SQLiteStmt).query(ctx, stmtArgs)
stmtArgs := stmtArgs(args, start, na)
rows, err := ss.query(ctx, stmtArgs)
if err != nil && err != driver.ErrSkip {
s.Close()
ss.Close()
return rows, err
}
start += na
tail := s.(*SQLiteStmt).t
tail := ss.t
if tail == "" {
return rows, nil
}
rows.Close()
s.Close()
ss.Close()
query = tail
}
}
@@ -1109,6 +1206,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
writableSchema := -1
vfsName := ""
var cacheSize *int64
stmtCacheSize := 0
pos := strings.IndexRune(dsn, '?')
if pos >= 1 {
@@ -1444,6 +1542,20 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
cacheSize = &iv
}
// _stmt_cache_size sets the maximum number of prepared statements
// cached per connection. Note that sql.DB is a connection pool, so
// each connection maintains its own independent cache.
if val := params.Get("_stmt_cache_size"); val != "" {
iv, err := strconv.Atoi(val)
if err != nil {
return nil, fmt.Errorf("Invalid _stmt_cache_size: %v: %v", val, err)
}
if iv < 0 {
return nil, fmt.Errorf("Invalid _stmt_cache_size: %v, expecting non-negative integer", val)
}
stmtCacheSize = iv
}
if val := params.Get("vfs"); val != "" {
vfsName = val
}
@@ -1517,6 +1629,10 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// Create connection to SQLite
conn := &SQLiteConn{db: db, loc: loc, txlock: txlock}
if stmtCacheSize > 0 {
conn.stmtCache = make([]*SQLiteStmt, 0, stmtCacheSize)
conn.stmtCacheEnabled = true
}
// Password Cipher has to be registered before authentication
if len(authCrypt) > 0 {
@@ -1789,6 +1905,7 @@ func (c *SQLiteConn) Close() error {
return nil
}
runtime.SetFinalizer(c, nil)
c.closeCachedStmtsLocked()
rv := C.sqlite3_close_v2(c.db)
if rv != C.SQLITE_OK {
return lastError(c.db)
@@ -1807,6 +1924,88 @@ func (c *SQLiteConn) dbConnOpen() bool {
return c.db != nil
}
func (c *SQLiteConn) takeCachedStmt(query string) *SQLiteStmt {
if c == nil || query == "" || !c.stmtCacheEnabled {
return nil
}
c.mu.Lock()
defer c.mu.Unlock()
if c.db == nil {
return nil
}
// Scan from the MRU end (tail) so that a stmt put just before is
// found immediately.
for i := len(c.stmtCache) - 1; i >= 0; i-- {
s := c.stmtCache[i]
if s.cacheKey != query {
continue
}
n := len(c.stmtCache)
copy(c.stmtCache[i:n-1], c.stmtCache[i+1:n])
c.stmtCache[n-1] = nil
c.stmtCache = c.stmtCache[:n-1]
// The stmt was marked closed by Close before being cached, and
// cls may have been set if Query opened it; reset both so the
// caller gets a stmt equivalent to a fresh Prepare.
s.closed = false
s.cls = false
return s
}
return nil
}
func (c *SQLiteConn) putCachedStmt(s *SQLiteStmt) bool {
if c == nil || s == nil || s.s == nil || s.cacheKey == "" {
return false
}
c.mu.Lock()
defer c.mu.Unlock()
if c.db == nil {
return false
}
rv := C._sqlite3_reset_clear(s.s)
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
return false
}
// If full, finalize the LRU entry at index 0 and shift left; the
// freed tail slot is immediately reused by the append below.
if len(c.stmtCache) == cap(c.stmtCache) {
finalizeCachedStmt(c.stmtCache[0])
copy(c.stmtCache, c.stmtCache[1:])
c.stmtCache = c.stmtCache[:len(c.stmtCache)-1]
}
c.stmtCache = append(c.stmtCache, s)
return true
}
func (c *SQLiteConn) closeCachedStmtsLocked() {
for i, s := range c.stmtCache {
c.stmtCache[i] = nil
finalizeCachedStmt(s)
}
c.stmtCache = c.stmtCache[:0]
}
// finalizeCachedStmt tears down a stmt that was sitting in the connection's
// stmt cache. The caller must hold c.mu. It is safe to pass a nil stmt or a
// stmt whose handle has already been released.
func finalizeCachedStmt(s *SQLiteStmt) {
if s == nil {
return
}
runtime.SetFinalizer(s, nil)
if s.s != nil {
C.sqlite3_finalize(s.s)
s.s = nil
}
s.c = nil
s.closed = true
}
// Prepare the query string. Return a new statement.
func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) {
return c.prepare(context.Background(), query)
@@ -1817,7 +2016,7 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
defer C.free(unsafe.Pointer(pquery))
var s *C.sqlite3_stmt
var tail *C.char
rv := C._sqlite3_prepare_v2_internal(c.db, pquery, C.int(-1), &s, &tail)
rv := C._sqlite3_prepare_v2_internal(c.db, pquery, C.int(len(query)), &s, &tail)
if rv != C.SQLITE_OK {
return nil, c.lastError()
}
@@ -1830,6 +2029,21 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
return ss, nil
}
func (c *SQLiteConn) prepareWithCache(ctx context.Context, query string) (driver.Stmt, error) {
if stmt := c.takeCachedStmt(query); stmt != nil {
return stmt, nil
}
stmt, err := c.prepare(ctx, query)
if err != nil {
return nil, err
}
ss := stmt.(*SQLiteStmt)
if ss.t == "" && c.stmtCacheEnabled {
ss.cacheKey = query
}
return ss, nil
}
// Run-Time Limit Categories.
// See: http://www.sqlite.org/c3ref/c_limit_attached.html
const (
@@ -1938,11 +2152,18 @@ func (s *SQLiteStmt) Close() error {
runtime.SetFinalizer(s, nil)
conn := s.c
stmt := s.s
s.s = nil
s.c = nil
if stmt == nil {
s.c = nil
return nil
}
if !conn.dbConnOpen() {
return errors.New("sqlite statement with already closed database connection")
}
if s.cacheKey != "" && conn.putCachedStmt(s) {
return nil
}
s.s = nil
s.c = nil
rv := C.sqlite3_finalize(stmt)
if rv != C.SQLITE_OK {
return conn.lastError()
@@ -1957,68 +2178,141 @@ func (s *SQLiteStmt) NumInput() int {
var placeHolder = []byte{0}
func bindText(s *C.sqlite3_stmt, n C.int, v string) C.int {
if len(v) == 0 {
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.sqlite3_uint64(0))
}
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(unsafe.StringData(v))), C.sqlite3_uint64(len(v)))
}
func bindValue(s *C.sqlite3_stmt, n C.int, value driver.Value) C.int {
switch v := value.(type) {
case nil:
return C.sqlite3_bind_null(s, n)
case string:
return bindText(s, n, v)
case int64:
return C.sqlite3_bind_int64(s, n, C.sqlite3_int64(v))
case bool:
if v {
return C.sqlite3_bind_int(s, n, 1)
}
return C.sqlite3_bind_int(s, n, 0)
case float64:
return C.sqlite3_bind_double(s, n, C.double(v))
case []byte:
if v == nil {
return C.sqlite3_bind_null(s, n)
}
ln := len(v)
if ln == 0 {
v = placeHolder
}
return C._sqlite3_bind_blob(s, n, unsafe.Pointer(&v[0]), C.sqlite3_uint64(ln))
case time.Time:
var buf [64]byte
b := v.AppendFormat(buf[:0], SQLiteTimestampFormats[0])
if len(b) == 0 {
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.sqlite3_uint64(0))
}
return C._sqlite3_bind_text(s, n, (*C.char)(unsafe.Pointer(&b[0])), C.sqlite3_uint64(len(b)))
default:
return C.SQLITE_MISUSE
}
}
func (s *SQLiteStmt) bindNamedIndices(name string) [3]int {
if s.namedParams == nil {
s.namedParams = make(map[string][3]int)
} else if indices, ok := s.namedParams[name]; ok {
return indices
}
// Build ":name\0" once and rewrite prefix byte to avoid 3 C.CString allocs.
buf := make([]byte, 1+len(name)+1) // prefix + name + null terminator
copy(buf[1:], name)
buf[len(buf)-1] = 0
cname := (*C.char)(unsafe.Pointer(&buf[0]))
var indices [3]int
prefixes := [3]byte{':', '@', '$'}
for i, p := range prefixes {
buf[0] = p
indices[i] = int(C.sqlite3_bind_parameter_index(s.s, cname))
}
s.namedParams[name] = indices
return indices
}
func stmtArgs(args []driver.NamedValue, start, na int) []driver.NamedValue {
if na == 0 {
return nil
}
end := start + na
hasNamedOutside := false
for i := range args {
if args[i].Name != "" && (i < start || i >= end) {
hasNamedOutside = true
break
}
}
if start == 0 && !hasNamedOutside {
return args[start:end]
}
stmtArgs := make([]driver.NamedValue, 0, len(args))
stmtArgs = append(stmtArgs, args[start:end]...)
for i := range args {
if args[i].Name != "" && (i < start || i >= end) {
stmtArgs = append(stmtArgs, args[i])
}
}
for i := range stmtArgs {
stmtArgs[i].Ordinal = i + 1
}
return stmtArgs
}
func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
rv := C.sqlite3_reset(s.s)
rv := C._sqlite3_reset_clear(s.s)
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
return s.c.lastError()
}
C.sqlite3_clear_bindings(s.s)
bindIndices := make([][3]int, len(args))
prefixes := []string{":", "@", "$"}
for i, v := range args {
bindIndices[i][0] = v.Ordinal
if v.Name != "" {
for j := range prefixes {
cname := C.CString(prefixes[j] + v.Name)
bindIndices[i][j] = int(C.sqlite3_bind_parameter_index(s.s, cname))
C.free(unsafe.Pointer(cname))
}
args[i].Ordinal = bindIndices[i][0]
hasNamed := false
for i := range args {
if args[i].Name != "" {
hasNamed = true
break
}
}
for i, arg := range args {
for j := range bindIndices[i] {
if bindIndices[i][j] == 0 {
if !hasNamed {
for _, arg := range args {
n := C.int(arg.Ordinal)
rv = bindValue(s.s, n, arg.Value)
if rv != C.SQLITE_OK {
return s.c.lastError()
}
}
return nil
}
for _, arg := range args {
if arg.Name == "" {
rv = bindValue(s.s, C.int(arg.Ordinal), arg.Value)
if rv != C.SQLITE_OK {
return s.c.lastError()
}
continue
}
indices := s.bindNamedIndices(arg.Name)
for _, idx := range indices {
if idx == 0 {
continue
}
n := C.int(bindIndices[i][j])
switch v := arg.Value.(type) {
case nil:
rv = C.sqlite3_bind_null(s.s, n)
case string:
if len(v) == 0 {
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&placeHolder[0])), C.int(0))
} else {
b := []byte(v)
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
}
case int64:
rv = C.sqlite3_bind_int64(s.s, n, C.sqlite3_int64(v))
case bool:
if v {
rv = C.sqlite3_bind_int(s.s, n, 1)
} else {
rv = C.sqlite3_bind_int(s.s, n, 0)
}
case float64:
rv = C.sqlite3_bind_double(s.s, n, C.double(v))
case []byte:
if v == nil {
rv = C.sqlite3_bind_null(s.s, n)
} else {
ln := len(v)
if ln == 0 {
v = placeHolder
}
rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(&v[0]), C.int(ln))
}
case time.Time:
b := []byte(v.Format(SQLiteTimestampFormats[0]))
rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b)))
}
rv = bindValue(s.s, C.int(idx), arg.Value)
if rv != C.SQLITE_OK {
return s.c.lastError()
}
@@ -2029,14 +2323,7 @@ func (s *SQLiteStmt) bind(args []driver.NamedValue) error {
// Query the statement with arguments. Return records.
func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) {
list := make([]driver.NamedValue, len(args))
for i, v := range args {
list[i] = driver.NamedValue{
Ordinal: i + 1,
Value: v,
}
}
return s.query(context.Background(), list)
return s.query(context.Background(), valueToNamedValue(args))
}
func (s *SQLiteStmt) query(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
@@ -2050,8 +2337,15 @@ func (s *SQLiteStmt) query(ctx context.Context, args []driver.NamedValue) (drive
cls: s.cls,
cols: nil,
decltype: nil,
colvals: nil,
ctx: ctx,
}
if rows.nc > 0 {
rows.colvals = (*C.sqlite3_go_col)(C.malloc(C.size_t(rows.nc) * C.size_t(unsafe.Sizeof(C.sqlite3_go_col{}))))
if rows.colvals == nil {
return nil, errors.New("sqlite3: failed to allocate row buffer")
}
}
return rows, nil
}
@@ -2068,6 +2362,10 @@ func (r *SQLiteResult) RowsAffected() (int64, error) {
// Exec execute the statement with arguments. Return result object.
func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) {
return s.exec(context.Background(), valueToNamedValue(args))
}
func valueToNamedValue(args []driver.Value) []driver.NamedValue {
list := make([]driver.NamedValue, len(args))
for i, v := range args {
list[i] = driver.NamedValue{
@@ -2075,7 +2373,7 @@ func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) {
Value: v,
}
}
return s.exec(context.Background(), list)
return list
}
func isInterruptErr(err error) bool {
@@ -2092,38 +2390,35 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []driver.NamedValue) (driver
return s.execSync(args)
}
type result struct {
r driver.Result
err error
}
resultCh := make(chan result)
defer close(resultCh)
sema := make(chan struct{})
var r driver.Result
var err error
go func() {
r, err := s.execSync(args)
resultCh <- result{r, err}
r, err = s.execSync(args)
close(sema)
}()
var rv result
select {
case rv = <-resultCh:
case <-sema:
return r, err
case <-ctx.Done():
select {
case rv = <-resultCh: // no need to interrupt, operation completed in db
case <-sema: // no need to interrupt, operation completed in db
return r, err
default:
// this is still racy and can be no-op if executed between sqlite3_* calls in execSync.
C.sqlite3_interrupt(s.c.db)
rv = <-resultCh // wait for goroutine completed
if isInterruptErr(rv.err) {
<-sema // wait for goroutine completed
if isInterruptErr(err) {
return nil, ctx.Err()
}
return r, err
}
}
return rv.r, rv.err
}
func (s *SQLiteStmt) execSync(args []driver.NamedValue) (driver.Result, error) {
if err := s.bind(args); err != nil {
C.sqlite3_reset(s.s)
C.sqlite3_clear_bindings(s.s)
C._sqlite3_reset_clear(s.s)
return nil, err
}
@@ -2131,8 +2426,7 @@ func (s *SQLiteStmt) execSync(args []driver.NamedValue) (driver.Result, error) {
rv := C._sqlite3_step_row_internal(s.s, &rowid, &changes)
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
err := s.c.lastError()
C.sqlite3_reset(s.s)
C.sqlite3_clear_bindings(s.s)
C._sqlite3_reset_clear(s.s)
return nil, err
}
@@ -2152,9 +2446,17 @@ func (rc *SQLiteRows) Close() error {
defer rc.closemu.Unlock()
s := rc.s
if s == nil {
if rc.colvals != nil {
C.free(unsafe.Pointer(rc.colvals))
rc.colvals = nil
}
return nil
}
rc.s = nil // remove reference to SQLiteStmt
if rc.colvals != nil {
C.free(unsafe.Pointer(rc.colvals))
rc.colvals = nil
}
s.mu.Lock()
if s.closed {
s.mu.Unlock()
@@ -2175,6 +2477,9 @@ func (rc *SQLiteRows) Close() error {
// Columns return column names.
func (rc *SQLiteRows) Columns() []string {
if rc.s == nil {
return rc.cols
}
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
if rc.s.s != nil && int(rc.nc) != len(rc.cols) {
@@ -2198,6 +2503,9 @@ func (rc *SQLiteRows) declTypes() []string {
// DeclTypes return column types.
func (rc *SQLiteRows) DeclTypes() []string {
if rc.s == nil {
return rc.decltype
}
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
return rc.declTypes()
@@ -2205,6 +2513,9 @@ func (rc *SQLiteRows) DeclTypes() []string {
// Next move cursor to next. Attempts to honor context timeout from QueryContext call.
func (rc *SQLiteRows) Next(dest []driver.Value) error {
if rc.s == nil {
return io.EOF
}
rc.s.mu.Lock()
defer rc.s.mu.Unlock()
@@ -2215,21 +2526,22 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
if rc.ctx.Done() == nil {
return rc.nextSyncLocked(dest)
}
resultCh := make(chan error)
defer close(resultCh)
sema := make(chan struct{})
var err error
go func() {
resultCh <- rc.nextSyncLocked(dest)
err = rc.nextSyncLocked(dest)
close(sema)
}()
select {
case err := <-resultCh:
case <-sema:
return err
case <-rc.ctx.Done():
select {
case <-resultCh: // no need to interrupt
case <-sema: // no need to interrupt
default:
// this is still racy and can be no-op if executed between sqlite3_* calls in nextSyncLocked.
C.sqlite3_interrupt(rc.s.c.db)
<-resultCh // ensure goroutine completed
<-sema // ensure goroutine completed
}
return rc.ctx.Err()
}
@@ -2250,13 +2562,19 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error {
}
rc.declTypes()
if len(dest) == 0 {
return nil
}
C._sqlite3_column_values(rc.s.s, C.int(len(dest)), rc.colvals)
colvals := (*[(math.MaxInt32 - 1) / unsafe.Sizeof(C.sqlite3_go_col{})]C.sqlite3_go_col)(unsafe.Pointer(rc.colvals))[:len(dest):len(dest)]
decltype := rc.decltype
_ = decltype[len(dest)-1]
for i := range dest {
switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
col := &colvals[i]
switch col.typ {
case C.SQLITE_INTEGER:
val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
val := int64(col.i64)
switch decltype[i] {
case columnTimestamp, columnDatetime, columnDate:
var t time.Time
@@ -2279,14 +2597,14 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error {
dest[i] = val
}
case C.SQLITE_FLOAT:
dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i)))
dest[i] = float64(col.f64)
case C.SQLITE_BLOB:
p := C.sqlite3_column_blob(rc.s.s, C.int(i))
p := col.ptr
if p == nil {
dest[i] = []byte{}
continue
}
n := C.sqlite3_column_bytes(rc.s.s, C.int(i))
n := col.n
dest[i] = C.GoBytes(p, n)
case C.SQLITE_NULL:
dest[i] = nil
@@ -2294,8 +2612,8 @@ func (rc *SQLiteRows) nextSyncLocked(dest []driver.Value) error {
var err error
var timeVal time.Time
n := int(C.sqlite3_column_bytes(rc.s.s, C.int(i)))
s := C.GoStringN((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i)))), C.int(n))
n := int(col.n)
s := C.GoStringN((*C.char)(unsafe.Pointer(col.ptr)), C.int(n))
switch decltype[i] {
case columnTimestamp, columnDatetime, columnDate:
+9 -4
View File
@@ -28,7 +28,6 @@ import "C"
import (
"math"
"reflect"
"unsafe"
)
@@ -91,9 +90,15 @@ func (c *SQLiteContext) ResultNull() {
// ResultText sets the result of an SQL function.
// See: sqlite3_result_text, http://sqlite.org/c3ref/result_blob.html
func (c *SQLiteContext) ResultText(s string) {
h := (*reflect.StringHeader)(unsafe.Pointer(&s))
cs, l := (*C.char)(unsafe.Pointer(h.Data)), C.int(h.Len)
C.my_result_text((*C.sqlite3_context)(c), cs, l)
if i64 && len(s) > math.MaxInt32 {
C.sqlite3_result_error_toobig((*C.sqlite3_context)(c))
return
}
if len(s) == 0 {
C.my_result_text((*C.sqlite3_context)(c), (*C.char)(unsafe.Pointer(&placeHolder[0])), 0)
return
}
C.my_result_text((*C.sqlite3_context)(c), (*C.char)(unsafe.Pointer(unsafe.StringData(s))), C.int(len(s)))
}
// ResultZeroblob sets the result of an SQL function.
+15
View File
@@ -0,0 +1,15 @@
// Copyright (C) 2025 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
// Copyright (C) 2025 Jakob Borg <jakob@kastelo.net>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
//go:build sqlite_dbstat
// +build sqlite_dbstat
package sqlite3
/*
#cgo CFLAGS: -DSQLITE_ENABLE_DBSTAT_VTAB
*/
import "C"
+2 -1
View File
@@ -21,6 +21,7 @@ package sqlite3
extern void unlock_notify_callback(void *arg, int argc);
*/
import "C"
import (
"fmt"
"math"
@@ -82,7 +83,7 @@ func unlock_notify_wait(db *C.sqlite3) C.int {
h := unt.add(c)
defer unt.remove(h)
pargv := C.malloc(C.sizeof_uint)
pargv := C.malloc(C.size_t(unsafe.Sizeof(uint(0))))
defer C.free(pargv)
argv := (*[1]uint)(pargv)
+5 -25
View File
@@ -270,7 +270,6 @@ import "C"
import (
"fmt"
"math"
"reflect"
"unsafe"
)
@@ -329,11 +328,7 @@ type InfoOrderBy struct {
}
func constraints(info *C.sqlite3_index_info) []InfoConstraint {
slice := *(*[]C.struct_sqlite3_index_constraint)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.aConstraint)),
Len: int(info.nConstraint),
Cap: int(info.nConstraint),
}))
slice := unsafe.Slice(info.aConstraint, int(info.nConstraint))
cst := make([]InfoConstraint, 0, len(slice))
for _, c := range slice {
@@ -351,11 +346,7 @@ func constraints(info *C.sqlite3_index_info) []InfoConstraint {
}
func orderBys(info *C.sqlite3_index_info) []InfoOrderBy {
slice := *(*[]C.struct_sqlite3_index_orderby)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.aOrderBy)),
Len: int(info.nOrderBy),
Cap: int(info.nOrderBy),
}))
slice := unsafe.Slice(info.aOrderBy, int(info.nOrderBy))
ob := make([]InfoOrderBy, 0, len(slice))
for _, c := range slice {
@@ -400,10 +391,7 @@ func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **
return 0
}
args := make([]string, argc)
var A []*C.char
slice := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(argv)), Len: int(argc), Cap: int(argc)}
a := reflect.NewAt(reflect.TypeOf(A), unsafe.Pointer(&slice)).Elem().Interface()
for i, s := range a.([]*C.char) {
for i, s := range unsafe.Slice(argv, int(argc)) {
args[i] = C.GoString(s)
}
var vTab VTab
@@ -466,11 +454,7 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
// Get a pointer to constraint_usage struct so we can update in place.
slice := *(*[]C.struct_sqlite3_index_constraint_usage)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.aConstraintUsage)),
Len: int(info.nConstraint),
Cap: int(info.nConstraint),
}))
slice := unsafe.Slice(info.aConstraintUsage, int(info.nConstraint))
index := 1
for i := range slice {
if res.Used[i] {
@@ -488,11 +472,7 @@ func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
}
info.needToFreeIdxStr = C.int(1)
idxStr := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(info.idxStr)),
Len: len(res.IdxStr) + 1,
Cap: len(res.IdxStr) + 1,
}))
idxStr := unsafe.Slice((*byte)(unsafe.Pointer(info.idxStr)), len(res.IdxStr)+1)
copy(idxStr, res.IdxStr)
idxStr[len(idxStr)-1] = 0 // null-terminated string
@@ -3,15 +3,14 @@
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
//go:build cgo && go1.8
// +build cgo,go1.8
//go:build cgo
// +build cgo
package sqlite3
import (
"database/sql/driver"
"context"
"database/sql/driver"
)
// Ping implement Pinger.
+10 -1
View File
@@ -376,7 +376,11 @@ struct sqlite3_api_routines {
/* Version 3.51.0 and later */
int (*set_errmsg)(sqlite3*,int,const char*);
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
/* Version 3.52.0 and later */
void (*str_truncate)(sqlite3_str*,int);
void (*str_free)(sqlite3_str*);
int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*));
int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*);
};
/*
@@ -715,6 +719,11 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.51.0 and later */
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
#define sqlite3_db_status64 sqlite3_api->db_status64
/* Version 3.52.0 and later */
#define sqlite3_str_truncate sqlite3_api->str_truncate
#define sqlite3_str_free sqlite3_api->str_free
#define sqlite3_carray_bind sqlite3_api->carray_bind
#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)