Index: sqlite3/src/main/jni/sqlite/sqlite3.c
==================================================================
--- sqlite3/src/main/jni/sqlite/sqlite3.c
+++ sqlite3/src/main/jni/sqlite/sqlite3.c
@@ -1,8 +1,8 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.25.3. By combining all the individual C code files into this
+** version 3.26.0. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
@@ -257,10 +257,13 @@
#if SQLITE_ENABLE_FTS4
"ENABLE_FTS4",
#endif
#if SQLITE_ENABLE_FTS5
"ENABLE_FTS5",
+#endif
+#if SQLITE_ENABLE_GEOPOLY
+ "ENABLE_GEOPOLY",
#endif
#if SQLITE_ENABLE_HIDDEN_COLUMNS
"ENABLE_HIDDEN_COLUMNS",
#endif
#if SQLITE_ENABLE_ICU
@@ -287,10 +290,13 @@
#if SQLITE_ENABLE_MEMSYS5
"ENABLE_MEMSYS5",
#endif
#if SQLITE_ENABLE_MULTIPLEX
"ENABLE_MULTIPLEX",
+#endif
+#if SQLITE_ENABLE_NORMALIZE
+ "ENABLE_NORMALIZE",
#endif
#if SQLITE_ENABLE_NULL_TRIM
"ENABLE_NULL_TRIM",
#endif
#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
@@ -1154,13 +1160,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.25.3"
-#define SQLITE_VERSION_NUMBER 3025003
-#define SQLITE_SOURCE_ID "2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b75036f2"
+#define SQLITE_VERSION "3.26.0"
+#define SQLITE_VERSION_NUMBER 3026000
+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
@@ -3048,10 +3054,11 @@
** the call worked. ^The [sqlite3_db_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
**
+** [[SQLITE_DBCONFIG_LOOKASIDE]]
** - SQLITE_DBCONFIG_LOOKASIDE
** - ^This option takes three additional arguments that determine the
** [lookaside memory allocator] configuration for the [database connection].
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.
@@ -3070,10 +3077,11 @@
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].)^
**
+** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
** - SQLITE_DBCONFIG_ENABLE_FKEY
** - ^This option is used to enable or disable the enforcement of
** [foreign key constraints]. There should be two additional arguments.
** The first argument is an integer which is 0 to disable FK enforcement,
** positive to enable FK enforcement or negative to leave FK enforcement
@@ -3080,10 +3088,11 @@
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether FK enforcement is off or on
** following this call. The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back.
**
+** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
** - SQLITE_DBCONFIG_ENABLE_TRIGGER
** - ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable triggers or negative to leave the setting unchanged.
@@ -3090,10 +3099,11 @@
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether triggers are disabled or enabled
** following this call. The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back.
**
+** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
** - SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
** - ^This option is used to enable or disable the two-argument
** version of the [fts3_tokenizer()] function which is part of the
** [FTS3] full-text search engine extension.
** There should be two additional arguments.
@@ -3103,10 +3113,11 @@
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
** following this call. The second parameter may be a NULL pointer, in
** which case the new setting is not reported back.
**
+** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
** - SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
** - ^This option is used to enable or disable the [sqlite3_load_extension()]
** interface independently of the [load_extension()] SQL function.
** The [sqlite3_enable_load_extension()] API enables or disables both the
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -3120,19 +3131,20 @@
** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
** is disabled or enabled following this call. The second parameter may
** be a NULL pointer, in which case the new setting is not reported back.
**
**
-** - SQLITE_DBCONFIG_MAINDBNAME
+** [[SQLITE_DBCONFIG_MAINDBNAME]] - SQLITE_DBCONFIG_MAINDBNAME
** - ^This option is used to change the name of the "main" database
** schema. ^The sole argument is a pointer to a constant UTF8 string
** which will become the new schema name in place of "main". ^SQLite
** does not make a copy of the new main schema name string, so the application
** must ensure that the argument passed into this DBCONFIG option is unchanged
** until after the database connection closes.
**
**
+** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
** - SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
** - Usually, when a database in wal mode is closed or detached from a
** database handle, SQLite checks if this will mean that there are now no
** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to
@@ -3142,11 +3154,11 @@
** The second parameter is a pointer to an integer
** into which is written 0 or 1 to indicate whether checkpoints-on-close
** have been disabled - 0 if they are not disabled, 1 if they are.
**
**
-** - SQLITE_DBCONFIG_ENABLE_QPSG
+** [[SQLITE_DBCONFIG_ENABLE_QPSG]] - SQLITE_DBCONFIG_ENABLE_QPSG
** - ^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
** a single SQL query statement will always use the same algorithm regardless
** of values of [bound parameters].)^ The QPSG disables some query optimizations
** that look at the values of bound parameters, which can make some queries
@@ -3158,11 +3170,11 @@
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
** following this call.
**
**
-** - SQLITE_DBCONFIG_TRIGGER_EQP
+** [[SQLITE_DBCONFIG_TRIGGER_EQP]] - SQLITE_DBCONFIG_TRIGGER_EQP
** - By default, the output of EXPLAIN QUERY PLAN commands does not
** include output for any operations performed by trigger programs. This
** option is used to set or clear (the default) a flag that governs this
** behavior. The first parameter passed to this operation is an integer -
** positive to enable output for trigger programs, or zero to disable it,
@@ -3170,11 +3182,11 @@
** The second parameter is a pointer to an integer into which is written
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
** it is not disabled, 1 if it is.
**
**
-** - SQLITE_DBCONFIG_RESET_DATABASE
+** [[SQLITE_DBCONFIG_RESET_DATABASE]] - SQLITE_DBCONFIG_RESET_DATABASE
** - Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
** [VACUUM] in order to reset a database back to an empty database
** with no schema and no content. The following process works even for
** a badly corrupted database file:
**
@@ -3189,10 +3201,22 @@
** - sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
**
** Because resetting a database is destructive and irreversible, the
** process requires the use of this obscure API and multiple steps to help
** ensure that it does not happen by accident.
+**
+** [[SQLITE_DBCONFIG_DEFENSIVE]] - SQLITE_DBCONFIG_DEFENSIVE
+** - The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
+** "defensive" flag for a database connection. When the defensive
+** flag is enabled, language features that allow ordinary SQL to
+** deliberately corrupt the database file are disabled. The disabled
+** features include but are not limited to the following:
+**
+** - The [PRAGMA writable_schema=ON] statement.
+**
- Writes to the [sqlite_dbpage] virtual table.
+**
- Direct writes to [shadow tables].
+**
**
**
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -3202,11 +3226,12 @@
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
-#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
** METHOD: sqlite3
**
@@ -4640,13 +4665,23 @@
** be used just once or at most a few times and then destroyed using
** [sqlite3_finalize()] relatively soon. The current implementation acts
** on this hint by avoiding the use of [lookaside memory] so as not to
** deplete the limited store of lookaside memory. Future versions of
** SQLite may act on this hint differently.
+**
+** [[SQLITE_PREPARE_NORMALIZE]] ^(SQLITE_PREPARE_NORMALIZE
+** The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
+** representation of the SQL statement should be calculated and then
+** associated with the prepared statement, which can be obtained via
+** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
+** normalize a SQL statement are unspecified and subject to change.
+** At a minimum, literal values will be replaced with suitable
+** placeholders.
**
*/
#define SQLITE_PREPARE_PERSISTENT 0x01
+#define SQLITE_PREPARE_NORMALIZE 0x02
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
@@ -4800,10 +4835,15 @@
** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
** string containing the SQL text of prepared statement P with
** [bound parameters] expanded.
+** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
+** string containing the normalized SQL text of prepared statement P. The
+** semantics used to normalize a SQL statement are unspecified and subject
+** to change. At a minimum, literal values will be replaced with suitable
+** placeholders.
**
** ^(For example, if a prepared statement is created using the SQL
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
** and parameter :xyz is unbound, then sqlite3_sql() will return
** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -4815,18 +4855,20 @@
**
** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
** option causes sqlite3_expanded_sql() to always return NULL.
**
-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
-** automatically freed when the prepared statement is finalized.
+** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
+** are managed by SQLite and are automatically freed when the prepared
+** statement is finalized.
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
** is obtained from [sqlite3_malloc()] and must be free by the application
** by passing it to [sqlite3_free()].
*/
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
** METHOD: sqlite3_stmt
**
@@ -7312,10 +7354,13 @@
/* The methods above are in version 1 of the sqlite_module object. Those
** below are for version 2 and greater. */
int (*xSavepoint)(sqlite3_vtab *pVTab, int);
int (*xRelease)(sqlite3_vtab *pVTab, int);
int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
+ /* The methods above are in versions 1 and 2 of the sqlite_module object.
+ ** Those below are for version 3 and greater. */
+ int (*xShadowName)(const char*);
};
/*
** CAPI3REF: Virtual Table Indexing Information
** KEYWORDS: sqlite3_index_info
@@ -8234,10 +8279,11 @@
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -9646,10 +9692,11 @@
** These macros define the various options to the
** [sqlite3_vtab_config()] interface that [virtual table] implementations
** can use to customize and optimize their behavior.
**
**
+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
** - SQLITE_VTAB_CONSTRAINT_SUPPORT
**
- Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
** where X is an integer. If X is zero, then the [virtual table] whose
** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -10415,11 +10462,11 @@
int iLevel; /* Level of current node or entry */
int mxLevel; /* The largest iLevel value in the tree */
sqlite3_int64 iRowid; /* Rowid for current entry */
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
int eParentWithin; /* Visibility of parent node */
- int eWithin; /* OUT: Visiblity */
+ int eWithin; /* OUT: Visibility */
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
/* The following fields are only available in 3.8.11 and later */
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
};
@@ -10911,16 +10958,42 @@
** an application iterates through a changeset using an iterator created by
** this function, all changes that relate to a single table are visited
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
** another change for table X.
+**
+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
+** may be modified by passing a combination of
+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
+**
+** Note that the sqlite3changeset_start_v2() API is still experimental
+** and therefore subject to change.
*/
SQLITE_API int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset /* Pointer to blob containing changeset */
);
+SQLITE_API int sqlite3changeset_start_v2(
+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
+ int nChangeset, /* Size of changeset blob in bytes */
+ void *pChangeset, /* Pointer to blob containing changeset */
+ int flags /* SESSION_CHANGESETSTART_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3changeset_start_v2
+**
+** The following flags may passed via the 4th parameter to
+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
+**
+**
- SQLITE_CHANGESETAPPLY_INVERT
-
+** Invert the changeset while iterating through it. This is equivalent to
+** inverting a changeset using sqlite3changeset_invert() before applying it.
+** It is an error to specify this flag with a patchset.
+*/
+#define SQLITE_CHANGESETSTART_INVERT 0x0002
/*
** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
@@ -11571,11 +11644,11 @@
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
- int flags /* Combination of SESSION_APPLY_* flags */
+ int flags /* SESSION_CHANGESETAPPLY_* flags */
);
/*
** CAPI3REF: Flags for sqlite3changeset_apply_v2
**
@@ -11589,12 +11662,18 @@
** SAVEPOINT is committed if the changeset or patchset is successfully
** applied, or rolled back if an error occurs. Specifying this flag
** causes the sessions module to omit this savepoint. In this case, if the
** caller has an open transaction or savepoint when apply_v2() is called,
** it may revert the partially applied changeset by rolling it back.
+**
+**
- SQLITE_CHANGESETAPPLY_INVERT
-
+** Invert the changeset before applying it. This is equivalent to inverting
+** a changeset using sqlite3changeset_invert() before applying it. It is
+** an error to specify this flag with a patchset.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
+#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
/*
** CAPI3REF: Constants Passed To The Conflict Handler
**
** Values that may be passed as the second argument to a conflict-handler.
@@ -11983,10 +12062,16 @@
);
SQLITE_API int sqlite3changeset_start_strm(
sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
+);
+SQLITE_API int sqlite3changeset_start_v2_strm(
+ sqlite3_changeset_iter **pp,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int flags
);
SQLITE_API int sqlite3session_changeset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
@@ -12010,10 +12095,49 @@
void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
+/*
+** CAPI3REF: Configure global parameters
+**
+** The sqlite3session_config() interface is used to make global configuration
+** changes to the sessions module in order to tune it to the specific needs
+** of the application.
+**
+** The sqlite3session_config() interface is not threadsafe. If it is invoked
+** while any other thread is inside any other sessions method then the
+** results are undefined. Furthermore, if it is invoked after any sessions
+** related objects have been created, the results are also undefined.
+**
+** The first argument to the sqlite3session_config() function must be one
+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
+** interpretation of the (void*) value passed as the second parameter and
+** the effect of calling this function depends on the value of the first
+** parameter.
+**
+**
+** - SQLITE_SESSION_CONFIG_STRMSIZE
-
+** By default, the sessions module streaming interfaces attempt to input
+** and output data in approximately 1 KiB chunks. This operand may be used
+** to set and query the value of this configuration setting. The pointer
+** passed as the second argument must point to a value of type (int).
+** If this value is greater than 0, it is used as the new streaming data
+** chunk size for both input and output. Before returning, the (int) value
+** pointed to by pArg is set to the final value of the streaming interface
+** chunk size.
+**
+**
+** This function returns SQLITE_OK if successful, or an SQLite error code
+** otherwise.
+*/
+SQLITE_API int sqlite3session_config(int op, void *pArg);
+
+/*
+** CAPI3REF: Values for sqlite3session_config().
+*/
+#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
** Make sure we can call this stuff from C++.
*/
#if 0
@@ -15275,22 +15399,21 @@
SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
-# ifdef SQLITE_DIRECT_OVERFLOW_READ
-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno);
-# endif
# ifdef SQLITE_ENABLE_SNAPSHOT
SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
-#else
-# define sqlite3PagerUseWal(x,y) 0
+#endif
+
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager);
#endif
@@ -15530,10 +15653,14 @@
SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
/* Number of dirty pages as a percentage of the configured cache size */
SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*);
+
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
+#endif
#endif /* _PCACHE_H_ */
/************** End of pcache.h **********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -16036,16 +16163,18 @@
/*
** A hash table for built-in function definitions. (Application-defined
** functions use a regular table table from hash.h.)
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
-** Collisions are on the FuncDef.u.pHash chain.
+** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH()
+** macro to compute a hash on the function name.
*/
#define SQLITE_FUNC_HASH_SZ 23
struct FuncDefHash {
FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
};
+#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ)
#ifdef SQLITE_USER_AUTHENTICATION
/*
** Information held in the "sqlite3" database connection object and used
** to manage user authentication.
@@ -16102,11 +16231,11 @@
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
sqlite3_mutex *mutex; /* Connection mutex */
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
u32 mDbFlags; /* flags recording internal state */
- u32 flags; /* flags settable by pragmas. See below */
+ u64 flags; /* flags settable by pragmas. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
i64 szMmap; /* Default mmap_size setting */
u32 nSchemaLock; /* Do not reset the schema when non-zero */
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
@@ -16268,18 +16397,21 @@
#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
#define SQLITE_ResetDatabase 0x02000000 /* Reset the database */
#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */
+#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/
+#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */
/* Flags used only if debugging */
+#define HI(X) ((u64)(X)<<32)
#ifdef SQLITE_DEBUG
-#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */
-#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */
-#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */
-#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */
+#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */
+#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */
+#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */
#endif
/*
** Allowed values for sqlite3.mDbFlags
*/
@@ -16409,12 +16541,13 @@
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
-#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */
-#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
+#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
+#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
+#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
**
@@ -16486,14 +16619,17 @@
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
-
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
+#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
+ {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
+ 0, 0, xFunc, 0, 0, 0, #zName, {0} }
+
/*
** All current savepoints are stored in a linked list starting at
** sqlite3.pSavepoint. The first element in the list is the most recently
** opened savepoint. Savepoints are added to the list by the vdbe
@@ -16674,10 +16810,13 @@
** by an instance of the following structure.
*/
struct Table {
char *zName; /* Name of the table or view */
Column *aCol; /* Information about each column */
+#ifdef SQLITE_ENABLE_NORMALIZE
+ Hash *pColHash; /* All columns indexed by name */
+#endif
Index *pIndex; /* List of SQL indexes on this table. */
Select *pSelect; /* NULL for tables. Points to definition if a view. */
FKey *pFKey; /* Linked list of all foreign keys in this table */
char *zColAff; /* String defining the affinity of each column */
ExprList *pCheck; /* All CHECK constraints */
@@ -16724,10 +16863,11 @@
#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
** Index.aiRowLogEst[] values */
#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
+#define TF_Shadow 0x0400 /* True for a shadow table */
/*
** Test to see whether or not a table is a virtual table. This is
** done as a macro so that it will be optimized out when virtual
** table support is omitted from the build.
@@ -17010,10 +17150,16 @@
tRowcnt *anEq; /* Est. number of rows where the key equals this sample */
tRowcnt *anLt; /* Est. number of rows where key is less than this sample */
tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
};
+/*
+** Possible values to use within the flags argument to sqlite3GetToken().
+*/
+#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */
+#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */
+
/*
** Each token coming out of the lexer is an instance of
** this structure. Tokens are also used as part of an expression.
**
** The memory that "z" points to is owned by other objects. Take care
@@ -17191,15 +17337,15 @@
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
u8 op2; /* TK_REGISTER: original value of Expr.op
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
- Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
- ** for a column of an index on an expression */
-#ifndef SQLITE_OMIT_WINDOWFUNC
- Window *pWin; /* Window definition for window functions */
-#endif
+ union {
+ Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
+ ** for a column of an index on an expression */
+ Window *pWin; /* TK_FUNCTION: Window definition for the func */
+ } y;
};
/*
** The following are the meanings of bits in the Expr.flags field.
*/
@@ -17225,10 +17371,11 @@
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias 0x400000 /* Is an alias for a result set column */
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
+#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
*/
@@ -18129,10 +18276,11 @@
#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
+ int bInternalFunctions; /* Internal SQL functions are visible */
int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
};
/*
@@ -18382,10 +18530,11 @@
/*
** Internal function prototypes
*/
SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*);
SQLITE_PRIVATE int sqlite3Strlen30(const char*);
+#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff)
SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*);
#define sqlite3StrNICmp sqlite3_strnicmp
SQLITE_PRIVATE int sqlite3MallocInit(void);
SQLITE_PRIVATE void sqlite3MallocEnd(void);
@@ -18498,10 +18647,11 @@
#if defined(SQLITE_DEBUG)
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
@@ -18730,15 +18880,19 @@
#endif
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int);
+#endif
SQLITE_PRIVATE void sqlite3GenerateRowDelete(
Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
u8,u8,int,int*,int*,Upsert*);
#ifdef SQLITE_ENABLE_NULL_TRIM
SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
#else
@@ -18755,10 +18909,13 @@
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int);
+#endif
SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int);
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
@@ -18912,10 +19069,11 @@
SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*);
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64);
@@ -18958,10 +19116,13 @@
SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
SQLITE_PRIVATE void sqlite3AlterFunctions(void);
SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *);
+#endif
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int);
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
@@ -19115,10 +19276,13 @@
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8);
+#endif
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
SQLITE_PRIVATE const char *sqlite3JournalModename(int);
@@ -19576,10 +19740,11 @@
#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
+ 0, /* bInternalFunctions */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
};
/*
@@ -20067,10 +20232,13 @@
bft bIsReader:1; /* True for statements that read */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
char *zSql; /* Text of the SQL statement that generated this */
+#ifdef SQLITE_ENABLE_NORMALIZE
+ char *zNormSql; /* Normalization of the associated SQL statement */
+#endif
void *pFree; /* Free this when deleting the vdbe */
VdbeFrame *pFrame; /* Parent frame */
VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */
int nFrame; /* Number of frames in pFrame list */
u32 expmask; /* Binding to these vars invalidates VM */
@@ -20129,11 +20297,13 @@
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
+#ifndef SQLITE_OMIT_EXPLAIN
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
+#endif
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
@@ -20168,11 +20338,13 @@
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
#endif
+#ifndef SQLITE_OMIT_EXPLAIN
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
+#endif
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*);
@@ -28295,10 +28467,46 @@
}
sqlite3TreeViewPop(pView);
}
}
+/*
+** Generate a human-readable description of a SrcList object.
+*/
+SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
+ int i;
+ for(i=0; inSrc; i++){
+ const struct SrcList_item *pItem = &pSrc->a[i];
+ StrAccum x;
+ char zLine[100];
+ sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+ sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
+ if( pItem->zDatabase ){
+ sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
+ }else if( pItem->zName ){
+ sqlite3_str_appendf(&x, " %s", pItem->zName);
+ }
+ if( pItem->pTab ){
+ sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
+ }
+ if( pItem->zAlias ){
+ sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
+ }
+ if( pItem->fg.jointype & JT_LEFT ){
+ sqlite3_str_appendf(&x, " LEFT-JOIN");
+ }
+ sqlite3StrAccumFinish(&x);
+ sqlite3TreeViewItem(pView, zLine, inSrc-1);
+ if( pItem->pSelect ){
+ sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+ }
+ if( pItem->fg.isTabFunc ){
+ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
+ }
+ sqlite3TreeViewPop(pView);
+ }
+}
/*
** Generate a human-readable description of a Select object.
*/
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
@@ -28349,43 +28557,13 @@
}
sqlite3TreeViewPop(pView);
}
#endif
if( p->pSrc && p->pSrc->nSrc ){
- int i;
pView = sqlite3TreeViewPush(pView, (n--)>0);
sqlite3TreeViewLine(pView, "FROM");
- for(i=0; ipSrc->nSrc; i++){
- struct SrcList_item *pItem = &p->pSrc->a[i];
- StrAccum x;
- char zLine[100];
- sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
- sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
- if( pItem->zDatabase ){
- sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
- }else if( pItem->zName ){
- sqlite3_str_appendf(&x, " %s", pItem->zName);
- }
- if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
- }
- if( pItem->zAlias ){
- sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
- }
- if( pItem->fg.jointype & JT_LEFT ){
- sqlite3_str_appendf(&x, " LEFT-JOIN");
- }
- sqlite3StrAccumFinish(&x);
- sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1);
- if( pItem->pSelect ){
- sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
- }
- if( pItem->fg.isTabFunc ){
- sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
- }
- sqlite3TreeViewPop(pView);
- }
+ sqlite3TreeViewSrcList(pView, p->pSrc);
sqlite3TreeViewPop(pView);
}
if( p->pWhere ){
sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
sqlite3TreeViewExpr(pView, p->pWhere, 0);
@@ -28671,11 +28849,11 @@
pFarg = 0;
pWin = 0;
}else{
pFarg = pExpr->x.pList;
#ifndef SQLITE_OMIT_WINDOWFUNC
- pWin = pExpr->pWin;
+ pWin = pExpr->y.pWin;
#else
pWin = 0;
#endif
}
if( pExpr->op==TK_AGG_FUNCTION ){
@@ -31499,10 +31677,24 @@
h += sqlite3UpperToLower[c];
h *= 0x9e3779b1;
}
return h;
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+static unsigned int strHashN(const char *z, int n){
+ unsigned int h = 0;
+ int i;
+ for(i=0; inext;
}
return &nullElement;
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+static HashElem *findElementWithHashN(
+ const Hash *pH, /* The pH to be searched */
+ const char *pKey, /* The key we are searching for */
+ int nKey, /* Number of key bytes to use */
+ unsigned int *pHash /* Write the hash value here */
+){
+ HashElem *elem; /* Used to loop thru the element list */
+ int count; /* Number of elements left to test */
+ unsigned int h; /* The computed hash */
+ static HashElem nullElement = { 0, 0, 0, 0 };
+
+ if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
+ struct _ht *pEntry;
+ h = strHashN(pKey, nKey) % pH->htsize;
+ pEntry = &pH->ht[h];
+ elem = pEntry->chain;
+ count = pEntry->count;
+ }else{
+ h = 0;
+ elem = pH->first;
+ count = pH->count;
+ }
+ if( pHash ) *pHash = h;
+ while( count-- ){
+ assert( elem!=0 );
+ if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){
+ return elem;
+ }
+ elem = elem->next;
+ }
+ return &nullElement;
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
*/
static void removeElementGivenHash(
@@ -31654,10 +31880,18 @@
SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
assert( pH!=0 );
assert( pKey!=0 );
return findElementWithHash(pH, pKey, 0)->data;
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){
+ assert( pH!=0 );
+ assert( pKey!=0 );
+ assert( nKey>=0 );
+ return findElementWithHashN(pH, pKey, nKey, 0)->data;
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
/* Insert an element into the hash table pH. The key is pKey
** and the data is "data".
**
** If no element exists with a matching key, then a new
@@ -32036,16 +32270,14 @@
** Allowed values of unixFile.fsFlags
*/
#define SQLITE_FSFLAGS_IS_MSDOS 0x1
/*
-** If we are to be thread-safe, include the pthreads header and define
-** the SQLITE_UNIX_THREADS macro.
+** If we are to be thread-safe, include the pthreads header.
*/
#if SQLITE_THREADSAFE
/* # include */
-# define SQLITE_UNIX_THREADS 1
#endif
/*
** Default permissions when creating a new file
*/
@@ -33217,12 +33449,11 @@
#endif
};
/*
** An instance of the following structure is allocated for each open
-** inode. Or, on LinuxThreads, there is one of these structures for
-** each inode opened by each thread.
+** inode.
**
** A single inode can have multiple file descriptors, so each unixFile
** structure contains a pointer to an instance of this object and this
** object keeps a count of the number of unixFile pointing to it.
**
@@ -33264,17 +33495,20 @@
#endif
};
/*
** A lists of all unixInodeInfo objects.
+**
+** Must hold unixBigLock in order to read or write this variable.
*/
static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
#ifdef SQLITE_DEBUG
/*
-** True if the inode mutex is held, or not. Used only within assert()
-** to help verify correct mutex usage.
+** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
+** This routine is used only within assert() to help verify correct mutex
+** usage.
*/
int unixFileMutexHeld(unixFile *pFile){
assert( pFile->pInode );
return sqlite3_mutex_held(pFile->pInode->pLockMutex);
}
@@ -33398,12 +33632,12 @@
}
/*
** Release a unixInodeInfo structure previously allocated by findInodeInfo().
**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
+** The global mutex must be held when this routine is called, but the mutex
+** on the inode being deleted must NOT be held.
*/
static void releaseInodeInfo(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
assert( unixMutexHeld() );
assert( unixFileMutexNotheld(pFile) );
@@ -33434,12 +33668,11 @@
/*
** Given a file descriptor, locate the unixInodeInfo object that
** describes that file descriptor. Create a new one if necessary. The
** return value might be uninitialized if an error occurs.
**
-** The mutex entered using the unixEnterMutex() function must be held
-** when this function is called.
+** The global mutex must held when calling this routine.
**
** Return an appropriate error code.
*/
static int findInodeInfo(
unixFile *pFile, /* Unix file with file desc used in the key */
@@ -33496,10 +33729,11 @@
#if OS_VXWORKS
fileId.pId = pFile->pId;
#else
fileId.ino = (u64)statbuf.st_ino;
#endif
+ assert( unixMutexHeld() );
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
}
if( pInode==0 ){
@@ -33515,10 +33749,11 @@
sqlite3_free(pInode);
return SQLITE_NOMEM_BKPT;
}
}
pInode->nRef = 1;
+ assert( unixMutexHeld() );
pInode->pNext = inodeList;
pInode->pPrev = 0;
if( inodeList ) inodeList->pPrev = pInode;
inodeList = pInode;
}else{
@@ -36312,22 +36547,22 @@
**
** nRef
**
** The following fields are read-only after the object is created:
**
-** fid
+** hShm
** zFilename
**
-** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
+** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and
** unixMutexHeld() is true when reading or writing any other field
** in this structure.
*/
struct unixShmNode {
unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */
- sqlite3_mutex *mutex; /* Mutex to access this object */
+ sqlite3_mutex *pShmMutex; /* Mutex to access this object */
char *zFilename; /* Name of the mmapped file */
- int h; /* Open file descriptor */
+ int hShm; /* Open file descriptor */
int szRegion; /* Size of shared-memory regions */
u16 nRegion; /* Size of array apRegion */
u8 isReadonly; /* True if read-only */
u8 isUnlocked; /* True if no DMS lock held */
char **apRegion; /* Array of mapped shared-memory regions */
@@ -36345,20 +36580,20 @@
** open shared memory connection.
**
** The following fields are initialized when this object is created and
** are read-only thereafter:
**
-** unixShm.pFile
+** unixShm.pShmNode
** unixShm.id
**
-** All other fields are read/write. The unixShm.pFile->mutex must be held
-** while accessing any read/write fields.
+** All other fields are read/write. The unixShm.pShmNode->pShmMutex must
+** be held while accessing any read/write fields.
*/
struct unixShm {
unixShmNode *pShmNode; /* The underlying unixShmNode object */
unixShm *pNext; /* Next unixShm with the same unixShmNode */
- u8 hasMutex; /* True if holding the unixShmNode mutex */
+ u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */
u8 id; /* Id of this connection within its unixShmNode */
u16 sharedMask; /* Mask of shared locks held */
u16 exclMask; /* Mask of exclusive locks held */
};
@@ -36384,25 +36619,26 @@
struct flock f; /* The posix advisory locking structure */
int rc = SQLITE_OK; /* Result code form fcntl() */
/* Access to the unixShmNode object is serialized by the caller */
pShmNode = pFile->pInode->pShmNode;
- assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
+ assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
+ assert( pShmNode->nRef>0 || unixMutexHeld() );
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
- rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
+ rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
}
/* Update the global lock state and do debug tracing */
#ifdef SQLITE_DEBUG
@@ -36470,22 +36706,22 @@
assert( unixMutexHeld() );
if( p && ALWAYS(p->nRef==0) ){
int nShmPerMap = unixShmRegionPerMap();
int i;
assert( p->pInode==pFd->pInode );
- sqlite3_mutex_free(p->mutex);
+ sqlite3_mutex_free(p->pShmMutex);
for(i=0; inRegion; i+=nShmPerMap){
- if( p->h>=0 ){
+ if( p->hShm>=0 ){
osMunmap(p->apRegion[i], p->szRegion);
}else{
sqlite3_free(p->apRegion[i]);
}
}
sqlite3_free(p->apRegion);
- if( p->h>=0 ){
- robust_close(pFd, p->h, __LINE__);
- p->h = -1;
+ if( p->hShm>=0 ){
+ robust_close(pFd, p->hShm, __LINE__);
+ p->hShm = -1;
}
p->pInode->pShmNode = 0;
sqlite3_free(p);
}
}
@@ -36523,19 +36759,24 @@
** system crash, the database itself may also become corrupt. */
lock.l_whence = SEEK_SET;
lock.l_start = UNIX_SHM_DMS;
lock.l_len = 1;
lock.l_type = F_WRLCK;
- if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
+ if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) {
rc = SQLITE_IOERR_LOCK;
}else if( lock.l_type==F_UNLCK ){
if( pShmNode->isReadonly ){
pShmNode->isUnlocked = 1;
rc = SQLITE_READONLY_CANTINIT;
}else{
rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
- if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
+ /* The first connection to attach must truncate the -shm file. We
+ ** truncate to 3 bytes (an arbitrary small number, less than the
+ ** -shm header size) rather than 0 as a system debugging aid, to
+ ** help detect if a -shm file truncation is legitimate or is the work
+ ** or a rogue process. */
+ if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){
rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
}
}
}else if( lock.l_type==F_WRLCK ){
rc = SQLITE_BUSY;
@@ -36637,28 +36878,28 @@
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
sqlite3FileSuffix3(pDbFd->zPath, zShm);
#endif
- pShmNode->h = -1;
+ pShmNode->hShm = -1;
pDbFd->pInode->pShmNode = pShmNode;
pShmNode->pInode = pDbFd->pInode;
if( sqlite3GlobalConfig.bCoreMutex ){
- pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
- if( pShmNode->mutex==0 ){
+ pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+ if( pShmNode->pShmMutex==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
}
if( pInode->bProcessLock==0 ){
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
}
- if( pShmNode->h<0 ){
- pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
- if( pShmNode->h<0 ){
+ if( pShmNode->hShm<0 ){
+ pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+ if( pShmNode->hShm<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
goto shm_open_err;
}
pShmNode->isReadonly = 1;
}
@@ -36665,11 +36906,11 @@
/* If this process is running as root, make sure that the SHM file
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
- robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
+ robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid);
rc = unixLockSharedMemory(pDbFd, pShmNode);
if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
}
}
@@ -36685,17 +36926,17 @@
/* The reference count on pShmNode has already been incremented under
** the cover of the unixEnterMutex() mutex and the pointer from the
** new (struct unixShm) object to the pShmNode has been set. All that is
** left to do is to link the new object into the linked list starting
- ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
- ** mutex.
+ ** at pShmNode->pFirst. This must be done while holding the
+ ** pShmNode->pShmMutex.
*/
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
return rc;
/* Jump here on any error */
shm_open_err:
unixShmPurge(pDbFd); /* This call frees pShmNode if required */
@@ -36743,20 +36984,20 @@
if( rc!=SQLITE_OK ) return rc;
}
p = pDbFd->pShm;
pShmNode = p->pShmNode;
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
if( pShmNode->isUnlocked ){
rc = unixLockSharedMemory(pDbFd, pShmNode);
if( rc!=SQLITE_OK ) goto shmpage_out;
pShmNode->isUnlocked = 0;
}
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
assert( pShmNode->pInode==pDbFd->pInode );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
/* Minimum number of regions required to be mapped. */
nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap;
if( pShmNode->nRegionszRegion = szRegion;
- if( pShmNode->h>=0 ){
+ if( pShmNode->hShm>=0 ){
/* 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).
*/
- if( osFstat(pShmNode->h, &sStat) ){
+ if( osFstat(pShmNode->hShm, &sStat) ){
rc = SQLITE_IOERR_SHMSIZE;
goto shmpage_out;
}
if( sStat.st_sizeh, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){
+ if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){
const char *zFile = pShmNode->zFilename;
rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile);
goto shmpage_out;
}
}
@@ -36820,26 +37061,26 @@
pShmNode->apRegion = apNew;
while( pShmNode->nRegionh>=0 ){
+ if( pShmNode->hShm>=0 ){
pMem = osMmap(0, nMap,
pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE,
- MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion
+ MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion
);
if( pMem==MAP_FAILED ){
rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename);
goto shmpage_out;
}
}else{
- pMem = sqlite3_malloc64(szRegion);
+ pMem = sqlite3_malloc64(nMap);
if( pMem==0 ){
rc = SQLITE_NOMEM_BKPT;
goto shmpage_out;
}
- memset(pMem, 0, szRegion);
+ memset(pMem, 0, nMap);
}
for(i=0; iapRegion[pShmNode->nRegion+i] = &((char*)pMem)[szRegion*i];
}
@@ -36852,11 +37093,11 @@
*pp = pShmNode->apRegion[iRegion];
}else{
*pp = 0;
}
if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
return rc;
}
/*
** Change the lock state for a shared-memory segment.
@@ -36886,16 +37127,16 @@
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 );
- assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
- assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
+ assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
+ assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
mask = (1<<(ofst+n)) - (1<1 || mask==(1<mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
if( flags & SQLITE_SHM_UNLOCK ){
u16 allMask = 0; /* Mask of locks held by siblings */
/* See if any siblings hold this same lock */
for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
@@ -36964,11 +37205,11 @@
assert( (p->sharedMask & mask)==0 );
p->exclMask |= mask;
}
}
}
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
p->id, osGetpid(0), p->sharedMask, p->exclMask));
return rc;
}
@@ -37014,27 +37255,27 @@
assert( pShmNode==pDbFd->pInode->pShmNode );
assert( pShmNode->pInode==pDbFd->pInode );
/* Remove connection p from the set of connections associated
** with pShmNode */
- sqlite3_mutex_enter(pShmNode->mutex);
+ sqlite3_mutex_enter(pShmNode->pShmMutex);
for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
*pp = p->pNext;
/* Free the connection p */
sqlite3_free(p);
pDbFd->pShm = 0;
- sqlite3_mutex_leave(pShmNode->mutex);
+ sqlite3_mutex_leave(pShmNode->pShmMutex);
/* If pShmNode->nRef has reached 0, then close the underlying
** shared-memory file, too */
assert( unixFileMutexNotheld(pDbFd) );
unixEnterMutex();
assert( pShmNode->nRef>0 );
pShmNode->nRef--;
if( pShmNode->nRef==0 ){
- if( deleteFlag && pShmNode->h>=0 ){
+ if( deleteFlag && pShmNode->hShm>=0 ){
osUnlink(pShmNode->zFilename);
}
unixShmPurge(pDbFd);
}
unixLeaveMutex();
@@ -40448,12 +40689,11 @@
#endif
#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; /* Usable size of mapped region */
- sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */
+ sqlite3_int64 mmapSize; /* Size of mapped region */
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
#endif
};
/*
@@ -43070,10 +43310,30 @@
winFile *pFile = (winFile*)id; /* File handle object */
int rc = SQLITE_OK; /* Return code for this function */
DWORD lastErrno;
#if SQLITE_MAX_MMAP_SIZE>0
sqlite3_int64 oldMmapSize;
+ if( pFile->nFetchOut>0 ){
+ /* File truncation is a no-op if there are outstanding memory mapped
+ ** pages. This is because truncating the file means temporarily unmapping
+ ** the file, and that might delete memory out from under existing cursors.
+ **
+ ** This can result in incremental vacuum not truncating the file,
+ ** if there is an active read cursor when the incremental vacuum occurs.
+ ** No real harm comes of this - the database file is not corrupted,
+ ** though some folks might complain that the file is bigger than it
+ ** needs to be.
+ **
+ ** The only feasible work-around is to defer the truncation until after
+ ** all references to memory-mapped content are closed. That is doable,
+ ** but involves adding a few branches in the common write code path which
+ ** could slow down normal operations slightly. Hence, we have decided for
+ ** now to simply make trancations a no-op if there are pending reads. We
+ ** can maybe revisit this decision in the future.
+ */
+ return SQLITE_OK;
+ }
#endif
assert( pFile );
SimulateIOError(return SQLITE_IOERR_TRUNCATE);
OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
@@ -44498,13 +44758,13 @@
*/
#if SQLITE_MAX_MMAP_SIZE>0
static int winUnmapfile(winFile *pFile){
assert( pFile!=0 );
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
- "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
+ "mmapSize=%lld, mmapSizeMax=%lld\n",
osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
- pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
+ pFile->mmapSize, pFile->mmapSizeMax));
if( pFile->pMapRegion ){
if( !osUnmapViewOfFile(pFile->pMapRegion) ){
pFile->lastErrno = osGetLastError();
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
"rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
@@ -44512,11 +44772,10 @@
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
"winUnmapfile1", pFile->zPath);
}
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
- pFile->mmapSizeActual = 0;
}
if( pFile->hMap!=NULL ){
if( !osCloseHandle(pFile->hMap) ){
pFile->lastErrno = osGetLastError();
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
@@ -44623,11 +44882,10 @@
osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
return SQLITE_OK;
}
pFd->pMapRegion = pNew;
pFd->mmapSize = nMap;
- pFd->mmapSizeActual = nMap;
}
OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFd));
return SQLITE_OK;
@@ -45425,11 +45683,10 @@
pFile->zPath = zName;
#if SQLITE_MAX_MMAP_SIZE>0
pFile->hMap = NULL;
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
- pFile->mmapSizeActual = 0;
pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
OpenCounter(+1);
return rc;
@@ -47322,11 +47579,11 @@
** pDirtyTail to the last (oldest).
**
** The PCache.pSynced variable is used to optimize searching for a dirty
** page to eject from the cache mid-transaction. It is better to eject
** a page that does not require a journal sync than one that does.
-** Therefore, pSynced is maintained to that it *almost* always points
+** Therefore, pSynced is maintained so that it *almost* always points
** to either the oldest page in the pDirty/pDirtyTail list that has a
** clear PGHDR_NEED_SYNC flag or to a page that is older than this one
** (so that the right page to eject can be found by following pDirtyPrev
** pointers).
*/
@@ -48145,10 +48402,19 @@
int nDirty = 0;
int nCache = numberOfCachePages(pCache);
for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext) nDirty++;
return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
}
+
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+/*
+** Return true if there are one or more dirty pages in the cache. Else false.
+*/
+SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){
+ return (pCache->pDirty!=0);
+}
+#endif
#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
/*
** For all dirty pages currently in the cache, invoke the specified
** callback. This is only used if the SQLITE_CHECK_PAGES macro is
@@ -48269,11 +48535,12 @@
PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
};
/*
-** A page is pinned if it is no on the LRU list
+** A page is pinned if it is not on the LRU list. To be "pinned" means
+** that the page is in active use and must not be deallocated.
*/
#define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
@@ -50909,23 +51176,34 @@
**
** if( pPager->jfd->pMethods ){ ...
*/
#define isOpen(pFd) ((pFd)->pMethods!=0)
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
/*
-** Return true if this pager uses a write-ahead log to read page pgno.
-** Return false if the pager reads pgno directly from the database.
+** Return true if page pgno can be read directly from the database file
+** by the b-tree layer. This is the case if:
+**
+** * the database file is open,
+** * there are no dirty pages in the cache, and
+** * the desired page is not currently in the wal file.
*/
-#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
-SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
- u32 iRead = 0;
- int rc;
- if( pPager->pWal==0 ) return 0;
- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
- return rc || iRead;
+SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
+ if( pPager->fd->pMethods==0 ) return 0;
+ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
+#ifndef SQLITE_OMIT_WAL
+ if( pPager->pWal ){
+ u32 iRead = 0;
+ int rc;
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
+ return (rc==SQLITE_OK && iRead==0);
+ }
+#endif
+ return 1;
}
#endif
+
#ifndef SQLITE_OMIT_WAL
# define pagerUseWal(x) ((x)->pWal!=0)
#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
@@ -57105,11 +57383,15 @@
void *(*xCodec)(void*,void*,Pgno,int),
void (*xCodecSizeChng)(void*,int,int),
void (*xCodecFree)(void*),
void *pCodec
){
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
+ if( pPager->xCodecFree ){
+ pPager->xCodecFree(pPager->pCodec);
+ }else{
+ pager_reset(pPager);
+ }
pPager->xCodec = pPager->memDb ? 0 : xCodec;
pPager->xCodecSizeChng = xCodecSizeChng;
pPager->xCodecFree = xCodecFree;
pPager->pCodec = pCodec;
setGetterMethod(pPager);
@@ -65765,11 +66047,11 @@
freeTempSpace(pBt);
rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
pageSize-usableSize);
return rc;
}
- if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){
+ if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){
rc = SQLITE_CORRUPT_BKPT;
goto page1_init_failed;
}
/* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
** be less than 480. In other words, if the page size is 512, then the
@@ -66239,10 +66521,11 @@
assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 ||
eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE );
assert( sqlite3_mutex_held(pBt->mutex) );
assert( pDbPage->pBt==pBt );
+ if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;
/* Move page iDbPage from its current location to page number iFreePage */
TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
iDbPage, iFreePage, iPtrPage, eType));
rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
@@ -67410,13 +67693,10 @@
offset -= ovflSize;
}else{
/* Need to read this page properly. It contains some of the
** range of data that is being read (eOp==0) or written (eOp!=0).
*/
-#ifdef SQLITE_DIRECT_OVERFLOW_READ
- sqlite3_file *fd; /* File from which to do direct overflow read */
-#endif
int a = amt;
if( a + offset > ovflSize ){
a = ovflSize - offset;
}
@@ -67423,11 +67703,11 @@
#ifdef SQLITE_DIRECT_OVERFLOW_READ
/* If all the following are true:
**
** 1) this is a read operation, and
** 2) data is required from the start of this overflow page, and
- ** 3) there is no open write-transaction, and
+ ** 3) there are no dirty pages in the page-cache
** 4) the database is file-backed, and
** 5) the page is not in the WAL file
** 6) at least 4 bytes have already been read into the output buffer
**
** then data can be read directly from the database file into the
@@ -67434,15 +67714,14 @@
** output buffer, bypassing the page-cache altogether. This speeds
** up loading large records that span many overflow pages.
*/
if( eOp==0 /* (1) */
&& offset==0 /* (2) */
- && pBt->inTransaction==TRANS_READ /* (3) */
- && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */
- && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */
+ && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */
&& &pBuf[-4]>=pBufStart /* (6) */
){
+ sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
u8 aSave[4];
u8 *aWrite = &pBuf[-4];
assert( aWrite>=pBufStart ); /* due to (6) */
memcpy(aSave, aWrite, 4);
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
@@ -74034,11 +74313,12 @@
sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
}else{
assert( fg & MEM_Real );
sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
}
- pMem->n = sqlite3Strlen30(pMem->z);
+ assert( pMem->z!=0 );
+ pMem->n = sqlite3Strlen30NN(pMem->z);
pMem->enc = SQLITE_UTF8;
pMem->flags |= MEM_Str|MEM_Term;
if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
sqlite3VdbeChangeEncoding(pMem, enc);
return SQLITE_OK;
@@ -75609,10 +75889,17 @@
if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){
p->expmask = 0;
}
assert( p->zSql==0 );
p->zSql = sqlite3DbStrNDup(p->db, z, n);
+#ifdef SQLITE_ENABLE_NORMALIZE
+ assert( p->zNormSql==0 );
+ if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){
+ sqlite3Normalize(p, p->zSql, n, prepFlags);
+ assert( p->zNormSql!=0 || p->db->mallocFailed );
+ }
+#endif
}
/*
** Swap all content between two VDBE structures.
*/
@@ -75630,10 +75917,15 @@
pA->pPrev = pB->pPrev;
pB->pPrev = pTmp;
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
+#ifdef SQLITE_ENABLE_NORMALIZE
+ zTmp = pA->zNormSql;
+ pA->zNormSql = pB->zNormSql;
+ pB->zNormSql = zTmp;
+#endif
pB->expmask = pA->expmask;
pB->prepFlags = pA->prepFlags;
memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter));
pB->aCounter[SQLITE_STMTSTATUS_REPREPARE]++;
}
@@ -78701,10 +78993,13 @@
sqlite3DbFree(db, p->pFree);
}
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
+#ifdef SQLITE_ENABLE_NORMALIZE
+ sqlite3DbFree(db, p->zNormSql);
+#endif
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
{
int i;
for(i=0; inScan; i++){
sqlite3DbFree(db, p->aScan[i].zName);
@@ -82115,10 +82410,20 @@
}
return z;
#endif
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Return the normalized SQL associated with a prepared statement.
+*/
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe *)pStmt;
+ return p ? p->zNormSql : 0;
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/*
** Allocate and populate an UnpackedRecord structure based on the serialized
** record in nKey/pKey. Return a pointer to the new UnpackedRecord structure
** if successful, or a NULL pointer if an OOM error is encountered.
@@ -85554,21 +85859,29 @@
nVarint = sqlite3VarintLen(nHdr);
nHdr += nVarint;
if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
/* Make sure the output register has a buffer large enough to store
** the new record. The output register (pOp->p3) is not allowed to
** be one of the input registers (because the following call to
** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
*/
- if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
- goto no_mem;
+ if( nByte+nZero<=pOut->szMalloc ){
+ /* The output register is already large enough to hold the record.
+ ** No error checks or buffer enlargement is required */
+ pOut->z = pOut->zMalloc;
+ }else{
+ /* Need to make sure that the output is not too big and then enlarge
+ ** the output register to hold the full result */
+ if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ goto too_big;
+ }
+ if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
+ goto no_mem;
+ }
}
zNewRecord = (u8 *)pOut->z;
/* Write the record */
i = putVarint32(zNewRecord, nHdr);
@@ -88420,11 +88733,11 @@
}else
#endif
{
zMaster = MASTER_NAME;
initData.db = db;
- initData.iDb = pOp->p1;
+ initData.iDb = iDb;
initData.pzErrMsg = &p->zErrMsg;
initData.mInitFlags = 0;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
@@ -94003,12 +94316,12 @@
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
}else if( pExpr->x.pList ){
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){
- Window *pWin = pExpr->pWin;
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ Window *pWin = pExpr->y.pWin;
if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort;
if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort;
}
#endif
@@ -94277,11 +94590,11 @@
**
** pExpr->iDb Set the index in db->aDb[] of the database X
** (even if X is implied).
** pExpr->iTable Set to the cursor number for the table obtained
** from pSrcList.
-** pExpr->pTab Points to the Table structure of X.Y (even if
+** pExpr->y.pTab Points to the Table structure of X.Y (even if
** X and/or Y are implied.)
** pExpr->iColumn Set to the column number within the table.
** pExpr->op Set to TK_COLUMN.
** pExpr->pLeft Any expression this points to is deleted
** pExpr->pRight Any expression this points to is deleted.
@@ -94321,11 +94634,10 @@
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
- pExpr->pTab = 0;
ExprSetVVAProperty(pExpr, EP_NoReduce);
/* Translate the schema name in zDb into a pointer to the corresponding
** schema. If not found, pSchema will remain NULL and nothing will match
** resulting in an appropriate error message toward the end of this routine
@@ -94383,11 +94695,11 @@
assert( zTabName!=0 );
if( sqlite3StrICmp(zTabName, zTab)!=0 ){
continue;
}
if( IN_RENAME_OBJECT && pItem->zAlias ){
- sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab);
+ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
}
}
if( 0==(cntTab++) ){
pMatch = pItem;
}
@@ -94409,17 +94721,17 @@
}
}
}
if( pMatch ){
pExpr->iTable = pMatch->iCursor;
- pExpr->pTab = pMatch->pTab;
+ pExpr->y.pTab = pMatch->pTab;
/* RIGHT JOIN not (yet) supported */
assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
ExprSetProperty(pExpr, EP_CanBeNull);
}
- pSchema = pExpr->pTab->pSchema;
+ pSchema = pExpr->y.pTab->pSchema;
}
} /* if( pSrcList ) */
#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT)
/* If we have not already resolved the name, then maybe
@@ -94472,11 +94784,11 @@
#ifndef SQLITE_OMIT_UPSERT
if( pExpr->iTable==2 ){
testcase( iCol==(-1) );
if( IN_RENAME_OBJECT ){
pExpr->iColumn = iCol;
- pExpr->pTab = pTab;
+ pExpr->y.pTab = pTab;
eNewExprOp = TK_COLUMN;
}else{
pExpr->iTable = pNC->uNC.pUpsert->regData + iCol;
eNewExprOp = TK_REGISTER;
ExprSetProperty(pExpr, EP_Alias);
@@ -94494,11 +94806,11 @@
}else{
testcase( iCol==31 );
testcase( iCol==32 );
pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<pTab = pTab;
+ pExpr->y.pTab = pTab;
pExpr->iColumn = (i16)iCol;
eNewExprOp = TK_TRIGGER;
#endif /* SQLITE_OMIT_TRIGGER */
}
}
@@ -94594,11 +94906,11 @@
*/
if( cnt==0 && zTab==0 ){
assert( pExpr->op==TK_ID );
if( ExprHasProperty(pExpr,EP_DblQuoted) ){
pExpr->op = TK_STRING;
- pExpr->pTab = 0;
+ pExpr->y.pTab = 0;
return WRC_Prune;
}
if( sqlite3ExprIdToTrueFalse(pExpr) ){
return WRC_Prune;
}
@@ -94672,13 +94984,13 @@
*/
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
if( p ){
struct SrcList_item *pItem = &pSrc->a[iSrc];
- p->pTab = pItem->pTab;
+ p->y.pTab = pItem->pTab;
p->iTable = pItem->iCursor;
- if( p->pTab->iPKey==iCol ){
+ if( p->y.pTab->iPKey==iCol ){
p->iColumn = -1;
}else{
p->iColumn = (ynVar)iCol;
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
@@ -94764,11 +95076,11 @@
struct SrcList_item *pItem;
assert( pSrcList && pSrcList->nSrc==1 );
pItem = pSrcList->a;
assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
pExpr->op = TK_COLUMN;
- pExpr->pTab = pItem->pTab;
+ pExpr->y.pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
pExpr->iColumn = -1;
pExpr->affinity = SQLITE_AFF_INTEGER;
break;
}
@@ -94808,13 +95120,11 @@
}
zTable = pLeft->u.zToken;
zColumn = pRight->u.zToken;
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
- }
- if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft);
+ sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
}
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
}
@@ -94892,30 +95202,39 @@
** sqlite_version() that might change over time cannot be used
** in an index. */
notValid(pParse, pNC, "non-deterministic functions",
NC_IdxExpr|NC_PartIdx);
}
+ if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
+ && pParse->nested==0
+ && sqlite3Config.bInternalFunctions==0
+ ){
+ /* Internal-use-only functions are disallowed unless the
+ ** SQL is being compiled using sqlite3NestedParse() */
+ no_such_func = 1;
+ pDef = 0;
+ }
}
if( 0==IN_RENAME_OBJECT ){
#ifndef SQLITE_OMIT_WINDOWFUNC
assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX)
|| (pDef->xValue==0 && pDef->xInverse==0)
|| (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize)
);
- if( pDef && pDef->xValue==0 && pExpr->pWin ){
+ if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){
sqlite3ErrorMsg(pParse,
"%.*s() may not be used as a window function", nId, zId
);
pNC->nErr++;
}else if(
(is_agg && (pNC->ncFlags & NC_AllowAgg)==0)
- || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin)
- || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0)
+ || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin)
+ || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0)
){
const char *zType;
- if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){
+ if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){
zType = "window";
}else{
zType = "aggregate";
}
sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId);
@@ -94941,30 +95260,30 @@
nId, zId);
pNC->nErr++;
}
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
- pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg);
+ pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
#else
pNC->ncFlags &= ~NC_AllowAgg;
#endif
}
}
sqlite3WalkExprList(pWalker, pList);
if( is_agg ){
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pExpr->pWin ){
+ if( pExpr->y.pWin ){
Select *pSel = pNC->pWinSelect;
- sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition);
- sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy);
- sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter);
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef);
+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition);
+ sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy);
+ sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
+ sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef);
if( 0==pSel->pWin
- || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin)
+ || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin)
){
- pExpr->pWin->pNextWin = pSel->pWin;
- pSel->pWin = pExpr->pWin;
+ pExpr->y.pWin->pNextWin = pSel->pWin;
+ pSel->pWin = pExpr->y.pWin;
}
pNC->ncFlags |= NC_AllowWin;
}else
#endif /* SQLITE_OMIT_WINDOWFUNC */
{
@@ -95383,17 +95702,17 @@
return 1;
}
for(j=0; jpEList->nExpr; j++){
if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( pE->pWin ){
+ if( ExprHasProperty(pE, EP_WinFunc) ){
/* Since this window function is being changed into a reference
** to the same window function the result set, remove the instance
** of this window function from the Select.pWin list. */
Window **pp;
for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){
- if( *pp==pE->pWin ){
+ if( *pp==pE->y.pWin ){
*pp = (*pp)->pNextWin;
}
}
}
#endif
@@ -95852,12 +96171,12 @@
if( op==TK_CAST ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){
- return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+ if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){
+ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
}
if( op==TK_SELECT_COLUMN ){
assert( pExpr->pLeft->flags&EP_xIsSelect );
return sqlite3ExprAffinity(
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
@@ -95937,17 +96256,17 @@
while( p ){
int op = p->op;
if( p->flags & EP_Generic ) break;
if( (op==TK_AGG_COLUMN || op==TK_COLUMN
|| op==TK_REGISTER || op==TK_TRIGGER)
- && p->pTab!=0
+ && p->y.pTab!=0
){
- /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
+ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */
int j = p->iColumn;
if( j>=0 ){
- const char *zColl = p->pTab->aCol[j].zColl;
+ const char *zColl = p->y.pTab->aCol[j].zColl;
pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
}
break;
}
if( op==TK_CAST || op==TK_UPLUS ){
@@ -96846,10 +97165,14 @@
*/
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
+
+ assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
+ assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
+ || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
#ifdef SQLITE_DEBUG
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->pLeft==0 );
assert( p->pRight==0 );
assert( p->x.pSelect==0 );
@@ -96864,12 +97187,13 @@
}else if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
sqlite3ExprListDelete(db, p->x.pList);
}
- if( !ExprHasProperty(p, EP_Reduced) ){
- sqlite3WindowDelete(db, p->pWin);
+ if( ExprHasProperty(p, EP_WinFunc) ){
+ assert( p->op==TK_FUNCTION );
+ sqlite3WindowDelete(db, p->y.pWin);
}
}
if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbFreeNN(db, p);
@@ -96929,11 +97253,11 @@
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
assert( EXPR_FULLSIZE<=0xfff );
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==flags || p->op==TK_SELECT_COLUMN
#ifndef SQLITE_OMIT_WINDOWFUNC
- || p->pWin
+ || ExprHasProperty(p, EP_WinFunc)
#endif
){
nSize = EXPR_FULLSIZE;
}else{
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -96956,11 +97280,11 @@
** string is defined.)
*/
static int dupedExprNodeSize(Expr *p, int flags){
int nByte = dupedExprStructSize(p, flags) & 0xfff;
if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
- nByte += sqlite3Strlen30(p->u.zToken)+1;
+ nByte += sqlite3Strlen30NN(p->u.zToken)+1;
}
return ROUND8(nByte);
}
/*
@@ -97059,26 +97383,28 @@
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
}
}
/* Fill in pNew->pLeft and pNew->pRight. */
- zAlloc += dupedExprNodeSize(p, dupFlags);
- if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
+ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){
+ zAlloc += dupedExprNodeSize(p, dupFlags);
if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
pNew->pLeft = p->pLeft ?
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
pNew->pRight = p->pRight ?
exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0;
}
- }else{
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){
- pNew->pWin = 0;
- }else{
- pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin);
+ if( ExprHasProperty(p, EP_WinFunc) ){
+ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin);
+ assert( ExprHasProperty(pNew, EP_WinFunc) );
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
+ if( pzBuffer ){
+ *pzBuffer = zAlloc;
+ }
+ }else{
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
assert( p->iColumn==0 || p->pRight==0 );
assert( p->pRight==0 || p->pRight==p->pLeft );
@@ -97086,13 +97412,10 @@
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
}
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
- if( pzBuffer ){
- *pzBuffer = zAlloc;
- }
}
return pNew;
}
/*
@@ -97883,12 +98206,12 @@
case TK_FLOAT:
case TK_BLOB:
return 0;
case TK_COLUMN:
return ExprHasProperty(p, EP_CanBeNull) ||
- p->pTab==0 || /* Reference to column of index on expression */
- (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
+ p->y.pTab==0 || /* Reference to column of index on expression */
+ (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
}
}
@@ -97939,10 +98262,18 @@
if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1;
if( sqlite3StrICmp(z, "ROWID")==0 ) return 1;
if( sqlite3StrICmp(z, "OID")==0 ) return 1;
return 0;
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){
+ if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1;
+ if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1;
+ if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1;
+ return 0;
+}
+#endif
/*
** pX is the RHS of an IN operator. If pX is a SELECT statement
** that can be simplified to a direct table access, then return
** a pointer to the SELECT statement. If pX is not a SELECT statement,
@@ -99172,11 +99503,11 @@
** expresssion. However, make sure the constant has the correct
** datatype by applying the Affinity of the table column to the
** constant.
*/
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
- int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+ int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
if( aff!=SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
if( iReg!=target ){
@@ -99196,11 +99527,11 @@
/* Coding an expression that is part of an index where column names
** in the index refer to the table to which the index belongs */
iTab = pParse->iSelfTab - 1;
}
}
- return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+ return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
@@ -99410,12 +99741,12 @@
sqlite3 *db = pParse->db; /* The database connection */
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
#ifndef SQLITE_OMIT_WINDOWFUNC
- if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){
- return pExpr->pWin->regResult;
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ return pExpr->y.pWin->regResult;
}
#endif
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
/* SQL functions can be expensive. So try to move constant functions
@@ -99654,11 +99985,11 @@
**
** p1==0 -> old.rowid p1==3 -> new.rowid
** p1==1 -> old.a p1==4 -> new.a
** p1==2 -> old.b p1==5 -> new.b
*/
- Table *pTab = pExpr->pTab;
+ Table *pTab = pExpr->y.pTab;
int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
assert( pExpr->iTable==0 || pExpr->iTable==1 );
assert( pExpr->iColumn>=-1 && pExpr->iColumnnCol );
assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
@@ -99665,11 +99996,11 @@
assert( p1>=0 && p1<(pTab->nCol*2+2) );
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "r[%d]=%s.%s", target,
(pExpr->iTable ? "new" : "old"),
- (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName)
+ (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
));
#ifndef SQLITE_OMIT_FLOATING_POINT
/* If the column has REAL affinity, it may currently be stored as an
** integer. Use OP_RealAffinity to make sure it is really real.
@@ -100516,10 +100847,24 @@
return 2;
}
if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
if( pA->op==TK_FUNCTION ){
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ /* Justification for the assert():
+ ** window functions have p->op==TK_FUNCTION but aggregate functions
+ ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
+ ** function and a window function should have failed before reaching
+ ** this point. And, it is not possible to have a window function and
+ ** a scalar function with the same name and number of arguments. So
+ ** if we reach this point, either A and B both window functions or
+ ** neither are a window functions. */
+ assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) );
+ if( ExprHasProperty(pA,EP_WinFunc) ){
+ if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2;
+ }
+#endif
}else if( pA->op==TK_COLLATE ){
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
}else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
}
@@ -100535,25 +100880,10 @@
if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
}
-#ifndef SQLITE_OMIT_WINDOWFUNC
- /* Justification for the assert():
- ** window functions have p->op==TK_FUNCTION but aggregate functions
- ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate
- ** function and a window function should have failed before reaching
- ** this point. And, it is not possible to have a window function and
- ** a scalar function with the same name and number of arguments. So
- ** if we reach this point, either A and B both window functions or
- ** neither are a window functions. */
- assert( (pA->pWin==0)==(pB->pWin==0) );
-
- if( pA->pWin!=0 ){
- if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2;
- }
-#endif
}
return 0;
}
/*
@@ -100690,12 +101020,12 @@
testcase( pExpr->op==TK_NE );
testcase( pExpr->op==TK_LT );
testcase( pExpr->op==TK_LE );
testcase( pExpr->op==TK_GT );
testcase( pExpr->op==TK_GE );
- if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab))
- || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab))
+ if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
+ || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
){
return WRC_Prune;
}
default:
return WRC_Continue;
@@ -100922,11 +101252,11 @@
}
if( (k>=pAggInfo->nColumn)
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
){
pCol = &pAggInfo->aCol[k];
- pCol->pTab = pExpr->pTab;
+ pCol->pTab = pExpr->y.pTab;
pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn;
pCol->iMem = ++pParse->nMem;
pCol->iSorterColumn = -1;
pCol->pExpr = pExpr;
@@ -101805,14 +102135,20 @@
#else
# define renameTokenCheckAll(x,y)
#endif
/*
-** Add a new RenameToken object mapping parse tree element pPtr into
-** token *pToken to the Parse object currently under construction.
+** Remember that the parser tree element pPtr was created using
+** the token pToken.
**
-** Return a copy of pPtr.
+** In other words, construct a new RenameToken object and add it
+** to the list of RenameToken objects currently being built up
+** in pParse->pRename.
+**
+** The pPtr argument is returned so that this routine can be used
+** with tail recursion in tokenExpr() routine, for a small performance
+** improvement.
*/
SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
RenameToken *pNew;
assert( pPtr || pParse->db->mallocFailed );
renameTokenCheckAll(pParse, pPtr);
@@ -101941,11 +102277,11 @@
&& pWalker->pParse->pTriggerTab==p->pTab
){
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}else if( pExpr->op==TK_COLUMN
&& pExpr->iColumn==p->iCol
- && p->pTab==pExpr->pTab
+ && p->pTab==pExpr->y.pTab
){
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}
return WRC_Continue;
}
@@ -102199,13 +102535,18 @@
assert( pNew->pTabSchema );
pParse->pTriggerTab = sqlite3FindTable(db, pNew->table,
db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
);
pParse->eTriggerOp = pNew->op;
+ /* ALWAYS() because if the table of the trigger does not exist, the
+ ** error would have been hit before this point */
+ if( ALWAYS(pParse->pTriggerTab) ){
+ rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
+ }
/* Resolve symbols in WHEN clause */
- if( pNew->pWhen ){
+ if( rc==SQLITE_OK && pNew->pWhen ){
rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen);
}
for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){
if( pStep->pSelect ){
@@ -102315,19 +102656,12 @@
** Do a column rename operation on the CREATE statement given in zSql.
** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
** into zNew. The name should be quoted if bQuote is true.
**
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
-** Though accessible to application code, it is not intended for use by
-** applications. The existance of this function, and the way it works,
-** is subject to change without notice.
-**
-** If any of the parameters are out-of-bounds, then simply return NULL.
-** An out-of-bounds parameter can only occur when the application calls
-** this function directly. The parameters will always be well-formed when
-** this routine is invoked by the bytecode for a legitimate ALTER TABLE
-** statement.
+** It is only accessible to SQL created using sqlite3NestedParse(). It is
+** not reachable from ordinary SQL passed into sqlite3_prepare().
*/
static void renameColumnFunc(
sqlite3_context *context,
int NotUsed,
sqlite3_value **argv
@@ -102479,12 +102813,12 @@
/*
** Walker expression callback used by "RENAME TABLE".
*/
static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
RenameCtx *p = pWalker->u.pRename;
- if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){
- renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab);
+ if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
+ renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
}
return WRC_Continue;
}
/*
@@ -102577,11 +102911,11 @@
sqlite3WalkSelect(&sWalker, pTab->pSelect);
}
}else{
/* Modify any FK definitions to point to the new table. */
#ifndef SQLITE_OMIT_FOREIGN_KEY
- if( db->flags & SQLITE_ForeignKeys ){
+ if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){
FKey *pFKey;
for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
}
@@ -102731,13 +103065,13 @@
/*
** Register built-in functions used to help implement ALTER TABLE
*/
SQLITE_PRIVATE void sqlite3AlterFunctions(void){
static FuncDef aAlterTableFuncs[] = {
- FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc),
- FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc),
- FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest),
+ INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
+ INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc),
+ INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest),
};
sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif /* SQLITE_ALTER_TABLE */
@@ -104782,11 +105116,11 @@
if( pVfs==0 ) return;
pNew = &db->aDb[db->init.iDb];
if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
pNew->pBt = 0;
pNew->pSchema = 0;
- rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+ rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
}else{
/* This is a real ATTACH
**
** Check for the following errors:
**
@@ -105462,10 +105796,11 @@
int iSrc; /* Index in pTabList->a[] of table being read */
int iDb; /* The index of the database the expression refers to */
int iCol; /* Index of column in table */
assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER );
+ assert( !IN_RENAME_OBJECT || db->xAuth==0 );
if( db->xAuth==0 ) return;
iDb = sqlite3SchemaToIndex(pParse->db, pSchema);
if( iDb<0 ){
/* An attempt to read a column out of a subquery or other
** temporary table. */
@@ -105518,10 +105853,11 @@
int rc;
/* Don't do any authorization checks if the database is initialising
** or if the parser is being invoked from within sqlite3_declare_vtab.
*/
+ assert( !IN_RENAME_OBJECT || db->xAuth==0 );
if( db->init.busy || IN_SPECIAL_PARSE ){
return SQLITE_OK;
}
if( db->xAuth==0 ){
@@ -105941,21 +106277,19 @@
p = sqlite3FindTable(db, zName, zDbase);
if( p==0 ){
const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3FindDbName(db, zDbase)<1 ){
- /* If zName is the not the name of a table in the schema created using
- ** CREATE, then check to see if it is the name of an virtual table that
- ** can be an eponymous virtual table. */
- Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
- if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
- pMod = sqlite3PragmaVtabRegister(db, zName);
- }
- if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
- return pMod->pEpoTab;
- }
+ /* If zName is the not the name of a table in the schema created using
+ ** CREATE, then check to see if it is the name of an virtual table that
+ ** can be an eponymous virtual table. */
+ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
+ if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
+ pMod = sqlite3PragmaVtabRegister(db, zName);
+ }
+ if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
+ return pMod->pEpoTab;
}
#endif
if( (flags & LOCATE_NOERR)==0 ){
if( zDbase ){
sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
@@ -106131,21 +106465,26 @@
** "main" and "temp") for a single database connection.
*/
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
int i;
sqlite3BtreeEnterAll(db);
- assert( db->nSchemaLock==0 );
for(i=0; inDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
- sqlite3SchemaClear(pDb->pSchema);
+ if( db->nSchemaLock==0 ){
+ sqlite3SchemaClear(pDb->pSchema);
+ }else{
+ DbSetProperty(db, i, DB_ResetWanted);
+ }
}
}
db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
- sqlite3CollapseDatabaseArray(db);
+ if( db->nSchemaLock==0 ){
+ sqlite3CollapseDatabaseArray(db);
+ }
}
/*
** This routine is called when a commit occurs.
*/
@@ -106218,10 +106557,16 @@
/* Delete any foreign keys attached to this table. */
sqlite3FkDelete(db, pTable);
/* Delete the Table structure itself.
*/
+#ifdef SQLITE_ENABLE_NORMALIZE
+ if( pTable->pColHash ){
+ sqlite3HashClear(pTable->pColHash);
+ sqlite3_free(pTable->pColHash);
+ }
+#endif
sqlite3DeleteColumnNames(db, pTable);
sqlite3DbFree(db, pTable->zName);
sqlite3DbFree(db, pTable->zColAff);
sqlite3SelectDelete(db, pTable->pSelect);
sqlite3ExprListDelete(db, pTable->pCheck);
@@ -106375,10 +106720,24 @@
iDb = db->init.iDb;
*pUnqual = pName1;
}
return iDb;
}
+
+/*
+** True if PRAGMA writable_schema is ON
+*/
+SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 );
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
+ SQLITE_WriteSchema );
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
+ SQLITE_Defensive );
+ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==
+ (SQLITE_WriteSchema|SQLITE_Defensive) );
+ return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
+}
/*
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
** trigger). All names are legal except those that begin with the string
@@ -106385,11 +106744,11 @@
** "sqlite_" (in upper, lower or mixed case). This portion of the namespace
** is reserved for internal use.
*/
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
if( !pParse->db->init.busy && pParse->nested==0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
+ && sqlite3WritableSchema(pParse->db)==0
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName);
return SQLITE_ERROR;
}
return SQLITE_OK;
@@ -107461,10 +107820,40 @@
pPk->nColumn = pTab->nCol;
}
recomputeColumnsNotIndexed(pPk);
}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Return true if zName is a shadow table name in the current database
+** connection.
+**
+** zName is temporarily modified while this routine is running, but is
+** restored to its original value prior to this routine returning.
+*/
+static int isShadowTableName(sqlite3 *db, char *zName){
+ char *zTail; /* Pointer to the last "_" in zName */
+ Table *pTab; /* Table that zName is a shadow of */
+ Module *pMod; /* Module for the virtual table */
+
+ zTail = strrchr(zName, '_');
+ if( zTail==0 ) return 0;
+ *zTail = 0;
+ pTab = sqlite3FindTable(db, zName, 0);
+ *zTail = '_';
+ if( pTab==0 ) return 0;
+ if( !IsVirtual(pTab) ) return 0;
+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
+ if( pMod==0 ) return 0;
+ if( pMod->pModule->iVersion<3 ) return 0;
+ if( pMod->pModule->xShadowName==0 ) return 0;
+ return pMod->pModule->xShadowName(zTail+1);
+}
+#else
+# define isShadowTableName(x,y) 0
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+
/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
@@ -107499,10 +107888,14 @@
return;
}
assert( !db->mallocFailed );
p = pParse->pNewTable;
if( p==0 ) return;
+
+ if( pSelect==0 && isShadowTableName(db, p->zName) ){
+ p->tabFlags |= TF_Shadow;
+ }
/* If the db->init.busy is 1 it means we are reading the SQL off the
** "sqlite_master" or "sqlite_temp_master" table on the disk.
** So do not write to the disk again. Extract the root page number
** for the table from the db->init.newTnum field. (The page number
@@ -108007,11 +108400,11 @@
** erasing iTable (this can happen with an auto-vacuum database).
*/
static void destroyRootPage(Parse *pParse, int iTable, int iDb){
Vdbe *v = sqlite3GetVdbe(pParse);
int r1 = sqlite3GetTempReg(pParse);
- assert( iTable>1 );
+ if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema");
sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb);
sqlite3MayAbort(pParse);
#ifndef SQLITE_OMIT_AUTOVACUUM
/* OP_Destroy stores an in integer r1. If this integer
** is non-zero, then it is the root page number of a table moved to
@@ -110462,10 +110855,25 @@
return p;
}
}
return 0;
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(
+ int h, /* Hash of the name */
+ const char *zFunc, /* Name of function */
+ int nFunc /* Length of the name */
+){
+ FuncDef *p;
+ for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
+ if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){
+ return p;
+ }
+ }
+ return 0;
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
/*
** Insert a new FuncDef into a FuncDefHash hash table.
*/
SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(
@@ -110475,11 +110883,11 @@
int i;
for(i=0; i='a' && zName[0]<='z' );
pOther = functionSearch(h, zName);
if( pOther ){
assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
aDef[i].pNext = pOther->pNext;
@@ -110554,11 +110962,11 @@
** new function. But the FuncDefs for built-in functions are read-only.
** So we must not search for built-ins when creating a new function.
*/
if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
bestScore = 0;
- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+ h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName);
p = functionSearch(h, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
pBest = p;
@@ -110701,37 +111109,54 @@
if( sqlite3IndexedByLookup(pParse, pItem) ){
pTab = 0;
}
return pTab;
}
+
+/* Return true if table pTab is read-only.
+**
+** A table is read-only if any of the following are true:
+**
+** 1) It is a virtual table and no implementation of the xUpdate method
+** has been provided
+**
+** 2) It is a system table (i.e. sqlite_master), this call is not
+** part of a nested parse and writable_schema pragma has not
+** been specified
+**
+** 3) The table is a shadow table, the database connection is in
+** defensive mode, and the current sqlite3_prepare()
+** is for a top-level SQL statement.
+*/
+static int tabIsReadOnly(Parse *pParse, Table *pTab){
+ sqlite3 *db;
+ if( IsVirtual(pTab) ){
+ return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
+ }
+ if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
+ db = pParse->db;
+ if( (pTab->tabFlags & TF_Readonly)!=0 ){
+ return sqlite3WritableSchema(db)==0 && pParse->nested==0;
+ }
+ assert( pTab->tabFlags & TF_Shadow );
+ return (db->flags & SQLITE_Defensive)!=0
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ && db->pVtabCtx==0
+#endif
+ && db->nVdbeExec==0;
+}
/*
** Check to make sure the given table is writable. If it is not
** writable, generate an error message and return 1. If it is
** writable return 0;
*/
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
- /* A table is not writable under the following circumstances:
- **
- ** 1) It is a virtual table and no implementation of the xUpdate method
- ** has been provided, or
- ** 2) It is a system table (i.e. sqlite_master), this call is not
- ** part of a nested parse and writable_schema pragma has not
- ** been specified.
- **
- ** In either case leave an error message in pParse and return non-zero.
- */
- if( ( IsVirtual(pTab)
- && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
- || ( (pTab->tabFlags & TF_Readonly)!=0
- && (pParse->db->flags & SQLITE_WriteSchema)==0
- && pParse->nested==0 )
- ){
+ if( tabIsReadOnly(pParse, pTab) ){
sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
return 1;
}
-
#ifndef SQLITE_OMIT_VIEW
if( !viewOk && pTab->pSelect ){
sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
return 1;
}
@@ -114131,11 +114556,11 @@
int iCursor, /* The open cursor on the table */
i16 iCol /* The column that is wanted */
){
Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
if( pExpr ){
- pExpr->pTab = pTab;
+ pExpr->y.pTab = pTab;
pExpr->iTable = iCursor;
pExpr->iColumn = iCol;
}
return pExpr;
}
@@ -115207,11 +115632,12 @@
do{
zColAff[i--] = 0;
}while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB );
pTab->zColAff = zColAff;
}
- i = sqlite3Strlen30(zColAff);
+ assert( zColAff!=0 );
+ i = sqlite3Strlen30NN(zColAff);
if( i ){
if( iReg ){
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
}else{
sqlite3VdbeChangeP4(v, -1, zColAff, i);
@@ -116187,18 +116613,19 @@
#ifdef tmask
#undef tmask
#endif
/*
-** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
+** Meanings of bits in of pWalker->eCode for
+** sqlite3ExprReferencesUpdatedColumn()
*/
#define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */
#define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */
-/* This is the Walker callback from checkConstraintUnchanged(). Set
-** bit 0x01 of pWalker->eCode if
-** pWalker->eCode to 0 if this expression node references any of the
+/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn().
+* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this
+** expression node references any of the
** columns that are being modifed by an UPDATE statement.
*/
static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_COLUMN ){
assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
@@ -116216,16 +116643,25 @@
/*
** pExpr is a CHECK constraint on a row that is being UPDATE-ed. The
** only columns that are modified by the UPDATE are those for which
** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
**
-** Return true if CHECK constraint pExpr does not use any of the
+** Return true if CHECK constraint pExpr uses any of the
** changing columns (or the rowid if it is changing). In other words,
-** return true if this CHECK constraint can be skipped when validating
+** return true if this CHECK constraint must be validated for
** the new row in the UPDATE statement.
+**
+** 2018-09-15: pExpr might also be an expression for an index-on-expressions.
+** The operation of this routine is the same - return true if an only if
+** the expression uses one or more of columns identified by the second and
+** third arguments.
*/
-static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
+SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(
+ Expr *pExpr, /* The expression to be checked */
+ int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */
+ int chngRowid /* True if UPDATE changes the rowid */
+){
Walker w;
memset(&w, 0, sizeof(w));
w.eCode = 0;
w.xExprCallback = checkConstraintExprNode;
w.u.aiCol = aiChng;
@@ -116236,11 +116672,11 @@
}
testcase( w.eCode==0 );
testcase( w.eCode==CKCNSTRNT_COLUMN );
testcase( w.eCode==CKCNSTRNT_ROWID );
testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
- return !w.eCode;
+ return w.eCode!=0;
}
/*
** Generate code to do constraint checks prior to an INSERT or an UPDATE
** on table pTab.
@@ -116442,11 +116878,17 @@
pParse->iSelfTab = -(regNewData+1);
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; inExpr; i++){
int allOk;
Expr *pExpr = pCheck->a[i].pExpr;
- if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
+ if( aiChng
+ && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
+ ){
+ /* The check constraints do not reference any of the columns being
+ ** updated so there is no point it verifying the check constraint */
+ continue;
+ }
allOk = sqlite3VdbeMakeLabel(v);
sqlite3VdbeVerifyAbortable(v, onError);
sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
if( onError==OE_Ignore ){
sqlite3VdbeGoto(v, ignoreDest);
@@ -117943,16 +118385,19 @@
void (*str_appendchar)(sqlite3_str*, int N, char C);
void (*str_reset)(sqlite3_str*);
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
+ /* Version 3.25.0 and later */
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
+ /* Version 3.26.0 and later */
+ const char *(*normalized_sql)(sqlite3_stmt*);
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
@@ -118236,10 +118681,12 @@
#define sqlite3_str_errcode sqlite3_api->str_errcode
#define sqlite3_str_length sqlite3_api->str_length
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
+/* Version 3.26.0 and later */
+#define sqlite3_normalized_sql sqlite3_api->normalized_sql
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
@@ -118324,10 +118771,11 @@
# define sqlite3_create_module 0
# define sqlite3_create_module_v2 0
# define sqlite3_declare_vtab 0
# define sqlite3_vtab_config 0
# define sqlite3_vtab_on_conflict 0
+# define sqlite3_vtab_collation 0
#endif
#ifdef SQLITE_OMIT_SHARED_CACHE
# define sqlite3_enable_shared_cache 0
#endif
@@ -118691,11 +119139,17 @@
sqlite3_str_reset,
sqlite3_str_errcode,
sqlite3_str_length,
sqlite3_str_value,
/* Version 3.25.0 and later */
- sqlite3_create_window_function
+ sqlite3_create_window_function,
+ /* Version 3.26.0 and later */
+#ifdef SQLITE_ENABLE_NORMALIZE
+ sqlite3_normalized_sql
+#else
+ 0
+#endif
};
/*
** Attempt to load an SQLite extension library contained in the file
** zFile. The entry point is zProc. zProc may be 0 in which case a
@@ -119141,14 +119595,13 @@
#define PragTyp_WAL_AUTOCHECKPOINT 38
#define PragTyp_WAL_CHECKPOINT 39
#define PragTyp_ACTIVATE_EXTENSIONS 40
#define PragTyp_HEXKEY 41
#define PragTyp_KEY 42
-#define PragTyp_REKEY 43
-#define PragTyp_LOCK_STATUS 44
-#define PragTyp_PARSER_TRACE 45
-#define PragTyp_STATS 46
+#define PragTyp_LOCK_STATUS 43
+#define PragTyp_PARSER_TRACE 44
+#define PragTyp_STATS 45
/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
@@ -119161,72 +119614,71 @@
/* Names of columns for pragmas that return multi-column result
** or that return single-column results where the name of the
** result column is different from the name of the pragma
*/
static const char *const pragCName[] = {
- /* 0 */ "cache_size", /* Used by: default_cache_size */
- /* 1 */ "cid", /* Used by: table_info */
- /* 2 */ "name",
- /* 3 */ "type",
- /* 4 */ "notnull",
- /* 5 */ "dflt_value",
- /* 6 */ "pk",
- /* 7 */ "tbl", /* Used by: stats */
- /* 8 */ "idx",
- /* 9 */ "wdth",
- /* 10 */ "hght",
- /* 11 */ "flgs",
- /* 12 */ "seqno", /* Used by: index_info */
- /* 13 */ "cid",
- /* 14 */ "name",
+ /* 0 */ "id", /* Used by: foreign_key_list */
+ /* 1 */ "seq",
+ /* 2 */ "table",
+ /* 3 */ "from",
+ /* 4 */ "to",
+ /* 5 */ "on_update",
+ /* 6 */ "on_delete",
+ /* 7 */ "match",
+ /* 8 */ "cid", /* Used by: table_xinfo */
+ /* 9 */ "name",
+ /* 10 */ "type",
+ /* 11 */ "notnull",
+ /* 12 */ "dflt_value",
+ /* 13 */ "pk",
+ /* 14 */ "hidden",
+ /* table_info reuses 8 */
/* 15 */ "seqno", /* Used by: index_xinfo */
/* 16 */ "cid",
/* 17 */ "name",
/* 18 */ "desc",
/* 19 */ "coll",
/* 20 */ "key",
- /* 21 */ "seq", /* Used by: index_list */
- /* 22 */ "name",
- /* 23 */ "unique",
- /* 24 */ "origin",
- /* 25 */ "partial",
- /* 26 */ "seq", /* Used by: database_list */
+ /* 21 */ "tbl", /* Used by: stats */
+ /* 22 */ "idx",
+ /* 23 */ "wdth",
+ /* 24 */ "hght",
+ /* 25 */ "flgs",
+ /* 26 */ "seq", /* Used by: index_list */
/* 27 */ "name",
- /* 28 */ "file",
- /* 29 */ "name", /* Used by: function_list */
- /* 30 */ "builtin",
- /* 31 */ "name", /* Used by: module_list pragma_list */
- /* 32 */ "seq", /* Used by: collation_list */
- /* 33 */ "name",
- /* 34 */ "id", /* Used by: foreign_key_list */
- /* 35 */ "seq",
- /* 36 */ "table",
- /* 37 */ "from",
- /* 38 */ "to",
- /* 39 */ "on_update",
- /* 40 */ "on_delete",
- /* 41 */ "match",
- /* 42 */ "table", /* Used by: foreign_key_check */
- /* 43 */ "rowid",
- /* 44 */ "parent",
- /* 45 */ "fkid",
- /* 46 */ "busy", /* Used by: wal_checkpoint */
- /* 47 */ "log",
- /* 48 */ "checkpointed",
- /* 49 */ "timeout", /* Used by: busy_timeout */
- /* 50 */ "database", /* Used by: lock_status */
- /* 51 */ "status",
+ /* 28 */ "unique",
+ /* 29 */ "origin",
+ /* 30 */ "partial",
+ /* 31 */ "table", /* Used by: foreign_key_check */
+ /* 32 */ "rowid",
+ /* 33 */ "parent",
+ /* 34 */ "fkid",
+ /* index_info reuses 15 */
+ /* 35 */ "seq", /* Used by: database_list */
+ /* 36 */ "name",
+ /* 37 */ "file",
+ /* 38 */ "busy", /* Used by: wal_checkpoint */
+ /* 39 */ "log",
+ /* 40 */ "checkpointed",
+ /* 41 */ "name", /* Used by: function_list */
+ /* 42 */ "builtin",
+ /* collation_list reuses 26 */
+ /* 43 */ "database", /* Used by: lock_status */
+ /* 44 */ "status",
+ /* 45 */ "cache_size", /* Used by: default_cache_size */
+ /* module_list pragma_list reuses 9 */
+ /* 46 */ "timeout", /* Used by: busy_timeout */
};
/* Definitions of all built-in pragmas */
typedef struct PragmaName {
const char *const zName; /* Name of pragma */
u8 ePragTyp; /* PragTyp_XXX value */
u8 mPragFlg; /* Zero or more PragFlg_XXX values */
u8 iPragCName; /* Start of column names in pragCName[] */
u8 nPragCName; /* Num of col names. 0 means use pragma name */
- u32 iArg; /* Extra argument */
+ u64 iArg; /* Extra argument */
} PragmaName;
static const PragmaName aPragmaName[] = {
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
{/* zName: */ "activate_extensions",
/* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
@@ -119258,11 +119710,11 @@
#endif
#endif
{/* zName: */ "busy_timeout",
/* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 49, 1,
+ /* ColNames: */ 46, 1,
/* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "cache_size",
/* ePragTyp: */ PragTyp_CACHE_SIZE,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
@@ -119295,11 +119747,11 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "collation_list",
/* ePragTyp: */ PragTyp_COLLATION_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 32, 2,
+ /* ColNames: */ 26, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
{/* zName: */ "compile_options",
/* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
@@ -119330,18 +119782,18 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "database_list",
/* ePragTyp: */ PragTyp_DATABASE_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
- /* ColNames: */ 26, 3,
+ /* ColNames: */ 35, 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: */ 0, 1,
+ /* ColNames: */ 45, 1,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{/* zName: */ "defer_foreign_keys",
@@ -119367,18 +119819,18 @@
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{/* zName: */ "foreign_key_check",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
- /* ColNames: */ 42, 4,
+ /* ColNames: */ 31, 4,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
{/* zName: */ "foreign_key_list",
/* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 34, 8,
+ /* ColNames: */ 0, 8,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
{/* zName: */ "foreign_keys",
@@ -119410,25 +119862,25 @@
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "function_list",
/* ePragTyp: */ PragTyp_FUNCTION_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 29, 2,
+ /* ColNames: */ 41, 2,
/* iArg: */ 0 },
#endif
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "hexkey",
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ 2 },
{/* zName: */ "hexrekey",
/* ePragTyp: */ PragTyp_HEXKEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ 3 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
{/* zName: */ "ignore_check_constraints",
/* ePragTyp: */ PragTyp_FLAG,
@@ -119446,16 +119898,16 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "index_info",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 12, 3,
+ /* ColNames: */ 15, 3,
/* iArg: */ 0 },
{/* zName: */ "index_list",
/* ePragTyp: */ PragTyp_INDEX_LIST,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 21, 5,
+ /* ColNames: */ 26, 5,
/* iArg: */ 0 },
{/* zName: */ "index_xinfo",
/* ePragTyp: */ PragTyp_INDEX_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
/* ColNames: */ 15, 6,
@@ -119508,11 +119960,11 @@
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
{/* zName: */ "lock_status",
/* ePragTyp: */ PragTyp_LOCK_STATUS,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 50, 2,
+ /* ColNames: */ 43, 2,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "locking_mode",
/* ePragTyp: */ PragTyp_LOCKING_MODE,
@@ -119534,11 +119986,11 @@
#if !defined(SQLITE_OMIT_VIRTUALTABLE)
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "module_list",
/* ePragTyp: */ PragTyp_MODULE_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 31, 1,
+ /* ColNames: */ 9, 1,
/* iArg: */ 0 },
#endif
#endif
#endif
{/* zName: */ "optimize",
@@ -119567,11 +120019,11 @@
#endif
#if defined(SQLITE_INTROSPECTION_PRAGMAS)
{/* zName: */ "pragma_list",
/* ePragTyp: */ PragTyp_PRAGMA_LIST,
/* ePragFlg: */ PragFlg_Result0,
- /* ColNames: */ 31, 1,
+ /* ColNames: */ 9, 1,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "query_only",
/* ePragTyp: */ PragTyp_FLAG,
@@ -119598,14 +120050,14 @@
/* ColNames: */ 0, 0,
/* iArg: */ SQLITE_RecTriggers },
#endif
#if defined(SQLITE_HAS_CODEC)
{/* zName: */ "rekey",
- /* ePragTyp: */ PragTyp_REKEY,
+ /* ePragTyp: */ PragTyp_KEY,
/* ePragFlg: */ 0,
/* ColNames: */ 0, 0,
- /* iArg: */ 0 },
+ /* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "reverse_unordered_selects",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119654,11 +120106,11 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
{/* zName: */ "stats",
/* ePragTyp: */ PragTyp_STATS,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
- /* ColNames: */ 7, 5,
+ /* ColNames: */ 21, 5,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "synchronous",
/* ePragTyp: */ PragTyp_SYNCHRONOUS,
@@ -119668,12 +120120,17 @@
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
{/* zName: */ "table_info",
/* ePragTyp: */ PragTyp_TABLE_INFO,
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
- /* ColNames: */ 1, 6,
+ /* ColNames: */ 8, 6,
/* iArg: */ 0 },
+ {/* zName: */ "table_xinfo",
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 8, 7,
+ /* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
{/* zName: */ "temp_store",
/* ePragTyp: */ PragTyp_TEMP_STORE,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
@@ -119682,10 +120139,22 @@
{/* zName: */ "temp_store_directory",
/* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
/* ePragFlg: */ PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ {/* zName: */ "textkey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 4 },
+ {/* zName: */ "textrekey",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 5 },
#endif
{/* zName: */ "threads",
/* ePragTyp: */ PragTyp_THREADS,
/* ePragFlg: */ PragFlg_Result0,
/* ColNames: */ 0, 0,
@@ -119733,22 +120202,22 @@
/* ColNames: */ 0, 0,
/* iArg: */ 0 },
{/* zName: */ "wal_checkpoint",
/* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
/* ePragFlg: */ PragFlg_NeedSchema,
- /* ColNames: */ 46, 3,
+ /* ColNames: */ 38, 3,
/* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
{/* zName: */ "writable_schema",
/* ePragTyp: */ PragTyp_FLAG,
/* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
/* ColNames: */ 0, 0,
- /* iArg: */ SQLITE_WriteSchema },
+ /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
-/* Number of pragmas: 61 on by default, 78 total. */
+/* Number of pragmas: 62 on by default, 81 total. */
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
/*
@@ -120756,11 +121225,11 @@
case PragTyp_FLAG: {
if( zRight==0 ){
setPragmaResultColumnNames(v, pPragma);
returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
}else{
- int mask = pPragma->iArg; /* Mask of bits to set or clear. */
+ u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
/* Foreign key support may not be enabled or disabled while not
** in auto-commit mode. */
mask &= ~(SQLITE_ForeignKeys);
}
@@ -120805,19 +121274,21 @@
*/
case PragTyp_TABLE_INFO: if( zRight ){
Table *pTab;
pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
if( pTab ){
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int i, k;
int nHidden = 0;
Column *pCol;
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
- pParse->nMem = 6;
- sqlite3CodeVerifySchema(pParse, iDb);
+ pParse->nMem = 7;
+ sqlite3CodeVerifySchema(pParse, iTabDb);
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
- if( IsHiddenColumn(pCol) ){
+ int isHidden = IsHiddenColumn(pCol);
+ if( isHidden && pPragma->iArg==0 ){
nHidden++;
continue;
}
if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
k = 0;
@@ -120825,17 +121296,18 @@
k = 1;
}else{
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
}
assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
- sqlite3VdbeMultiLoad(v, 1, "issisi",
+ sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
i-nHidden,
pCol->zName,
sqlite3ColumnType(pCol,""),
pCol->notNull ? 1 : 0,
pCol->pDflt ? pCol->pDflt->u.zToken : 0,
- k);
+ k,
+ isHidden);
}
}
}
break;
@@ -120869,10 +121341,11 @@
case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
Table *pTab;
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
+ int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema);
int i;
int mx;
if( pPragma->iArg ){
/* PRAGMA index_xinfo (newer version with more rows and columns) */
mx = pIdx->nColumn;
@@ -120881,11 +121354,11 @@
/* PRAGMA index_info (legacy version) */
mx = pIdx->nKeyCol;
pParse->nMem = 3;
}
pTab = pIdx->pTable;
- sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3CodeVerifySchema(pParse, iIdxDb);
assert( pParse->nMem<=pPragma->nPragCName );
for(i=0; iaiColumn[i];
sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum,
cnum<0 ? 0 : pTab->aCol[cnum].zName);
@@ -120905,12 +121378,13 @@
Index *pIdx;
Table *pTab;
int i;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pParse->nMem = 5;
- sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3CodeVerifySchema(pParse, iTabDb);
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
const char *azOrigin[] = { "c", "u", "pk" };
sqlite3VdbeMultiLoad(v, 1, "isisi",
i,
pIdx->zName,
@@ -120953,10 +121427,11 @@
HashElem *j;
FuncDef *p;
pParse->nMem = 2;
for(i=0; iu.pHash ){
+ if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
}
}
for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
p = (FuncDef*)sqliteHashData(j);
@@ -120994,13 +121469,14 @@
Table *pTab;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
pFK = pTab->pFKey;
if( pFK ){
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int i = 0;
pParse->nMem = 8;
- sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3CodeVerifySchema(pParse, iTabDb);
while(pFK){
int j;
for(j=0; jnCol; j++){
sqlite3VdbeMultiLoad(v, 1, "iissssss",
i,
@@ -121041,36 +121517,38 @@
regResult = pParse->nMem+1;
pParse->nMem += 4;
regKey = ++pParse->nMem;
regRow = ++pParse->nMem;
- sqlite3CodeVerifySchema(pParse, iDb);
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
while( k ){
+ int iTabDb;
if( zRight ){
pTab = sqlite3LocateTable(pParse, 0, zRight, zDb);
k = 0;
}else{
pTab = (Table*)sqliteHashData(k);
k = sqliteHashNext(k);
}
if( pTab==0 || pTab->pFKey==0 ) continue;
- sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
+ iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ sqlite3CodeVerifySchema(pParse, iTabDb);
+ sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
- sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
+ sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
sqlite3VdbeLoadString(v, regResult, pTab->zName);
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
if( pParent==0 ) continue;
pIdx = 0;
- sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
+ sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
if( x==0 ){
if( pIdx==0 ){
- sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
+ sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
}else{
- sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
}
}else{
k = 0;
break;
@@ -121835,16 +122313,28 @@
break;
}
#endif
#ifdef SQLITE_HAS_CODEC
+ /* Pragma iArg
+ ** ---------- ------
+ ** key 0
+ ** rekey 1
+ ** hexkey 2
+ ** hexrekey 3
+ ** textkey 4
+ ** textrekey 5
+ */
case PragTyp_KEY: {
- if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
- break;
- }
- case PragTyp_REKEY: {
- if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+ if( zRight ){
+ int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
+ if( (pPragma->iArg & 1)==0 ){
+ sqlite3_key_v2(db, zDb, zRight, n);
+ }else{
+ sqlite3_rekey_v2(db, zDb, zRight, n);
+ }
+ }
break;
}
case PragTyp_HEXKEY: {
if( zRight ){
u8 iByte;
@@ -121852,11 +122342,11 @@
char zKey[40];
for(i=0, iByte=0; iiArg & 1)==0 ){
sqlite3_key_v2(db, zDb, zKey, i/2);
}else{
sqlite3_rekey_v2(db, zDb, zKey, i/2);
}
}
@@ -122182,11 +122672,12 @@
0, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
0, /* xRename - rename the table */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
/*
** Check to see if zTabName is really the name of a pragma. If it is,
** then register an eponymous virtual table for that pragma and return
@@ -122535,12 +123026,12 @@
}
if( db->mallocFailed ){
rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
}
- if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){
- /* Black magic: If the SQLITE_WriteSchema flag is set, then consider
+ if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){
+ /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider
** the schema loaded, even if errors occurred. In this situation the
** current sqlite3_prepare() operation will fail, but the following one
** will attempt to compile the supplied statement against whatever subset
** of the schema was loaded before the error occurred. The primary
** purpose of this is to allow access to the sqlite_master table
@@ -122917,10 +123408,298 @@
assert( (rc&db->errMask)==rc );
sqlite3_mutex_leave(db->mutex);
return rc;
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Checks if the specified token is a table, column, or function name,
+** based on the databases associated with the statement being prepared.
+** If the function fails, zero is returned and pRc is filled with the
+** error code.
+*/
+static int shouldTreatAsIdentifier(
+ sqlite3 *db, /* Database handle. */
+ const char *zToken, /* Pointer to start of token to be checked */
+ int nToken, /* Length of token to be checked */
+ int *pRc /* Pointer to error code upon failure */
+){
+ int bFound = 0; /* Non-zero if token is an identifier name. */
+ int i, j; /* Database and column loop indexes. */
+ Schema *pSchema; /* Schema for current database. */
+ Hash *pHash; /* Hash table of tables for current database. */
+ HashElem *e; /* Hash element for hash table iteration. */
+ Table *pTab; /* Database table for columns being checked. */
+
+ if( sqlite3IsRowidN(zToken, nToken) ){
+ return 1;
+ }
+ if( nToken>0 ){
+ int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken);
+ if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1;
+ }
+ assert( db!=0 );
+ sqlite3_mutex_enter(db->mutex);
+ sqlite3BtreeEnterAll(db);
+ for(i=0; inDb; i++){
+ pHash = &db->aFunc;
+ if( sqlite3HashFindN(pHash, zToken, nToken) ){
+ bFound = 1;
+ break;
+ }
+ pSchema = db->aDb[i].pSchema;
+ if( pSchema==0 ) continue;
+ pHash = &pSchema->tblHash;
+ if( sqlite3HashFindN(pHash, zToken, nToken) ){
+ bFound = 1;
+ break;
+ }
+ for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){
+ pTab = sqliteHashData(e);
+ if( pTab==0 ) continue;
+ pHash = pTab->pColHash;
+ if( pHash==0 ){
+ pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash));
+ if( pHash ){
+ sqlite3HashInit(pHash);
+ for(j=0; jnCol; j++){
+ Column *pCol = &pTab->aCol[j];
+ sqlite3HashInsert(pHash, pCol->zName, pCol);
+ }
+ }else{
+ *pRc = SQLITE_NOMEM_BKPT;
+ bFound = 0;
+ goto done;
+ }
+ }
+ if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){
+ bFound = 1;
+ goto done;
+ }
+ }
+ }
+done:
+ sqlite3BtreeLeaveAll(db);
+ sqlite3_mutex_leave(db->mutex);
+ return bFound;
+}
+
+/*
+** Attempt to estimate the final output buffer size needed for the fully
+** normalized version of the specified SQL string. This should take into
+** account any potential expansion that could occur (e.g. via IN clauses
+** being expanded, etc). This size returned is the total number of bytes
+** including the NUL terminator.
+*/
+static int estimateNormalizedSize(
+ const char *zSql, /* The original SQL string */
+ int nSql, /* Length of original SQL string */
+ u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
+){
+ int nOut = nSql + 4;
+ const char *z = zSql;
+ while( nOut0 ){
+ zOut[j++] = '"';
+ continue;
+ }else if( k==nToken-1 ){
+ zOut[j++] = '"';
+ continue;
+ }
+ }
+ if( bKeyword ){
+ zOut[j++] = sqlite3Toupper(zSql[iIn+k]);
+ }else{
+ zOut[j++] = sqlite3Tolower(zSql[iIn+k]);
+ }
+ }
+ *piOut = j;
+}
+
+/*
+** Perform normalization of the SQL contained in the prepared statement and
+** store the result in the zNormSql field. The schema for the associated
+** databases are consulted while performing the normalization in order to
+** determine if a token appears to be an identifier. All identifiers are
+** left intact in the normalized SQL and all literals are replaced with a
+** single '?'.
+*/
+SQLITE_PRIVATE void sqlite3Normalize(
+ Vdbe *pVdbe, /* VM being reprepared */
+ const char *zSql, /* The original SQL string */
+ int nSql, /* Size of the input string in bytes */
+ u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */
+){
+ sqlite3 *db; /* Database handle. */
+ char *z; /* The output string */
+ int nZ; /* Size of the output string in bytes */
+ int i; /* Next character to read from zSql[] */
+ int j; /* Next character to fill in on z[] */
+ int tokenType = 0; /* Type of the next token */
+ int prevTokenType = 0; /* Type of the previous token, except spaces */
+ int n; /* Size of the next token */
+ int nParen = 0; /* Nesting level of parenthesis */
+ Hash inHash; /* Table of parenthesis levels to output index. */
+
+ db = sqlite3VdbeDb(pVdbe);
+ assert( db!=0 );
+ assert( pVdbe->zNormSql==0 );
+ if( zSql==0 ) return;
+ nZ = estimateNormalizedSize(zSql, nSql, prepFlags);
+ z = sqlite3DbMallocRawNN(db, nZ);
+ if( z==0 ) return;
+ sqlite3HashInit(&inHash);
+ for(i=j=0; i0 ){
+ sqlite3HashInsert(&inHash, zSql+nParen, 0);
+ assert( jj+6=0 );
+ assert( nZ-1-j=0 );
+ /* Fall through */
+ }
+ case TK_MINUS:
+ case TK_SEMI:
+ case TK_PLUS:
+ case TK_STAR:
+ case TK_SLASH:
+ case TK_REM:
+ case TK_EQ:
+ case TK_LE:
+ case TK_NE:
+ case TK_LSHIFT:
+ case TK_LT:
+ case TK_RSHIFT:
+ case TK_GT:
+ case TK_GE:
+ case TK_BITOR:
+ case TK_CONCAT:
+ case TK_COMMA:
+ case TK_BITAND:
+ case TK_BITNOT:
+ case TK_DOT:
+ case TK_IN:
+ case TK_IS:
+ case TK_NOT:
+ case TK_NULL:
+ case TK_ID: {
+ if( tokenType==TK_NULL ){
+ if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){
+ /* NULL is a keyword in this case, not a literal value */
+ }else{
+ /* Here the NULL is a literal value */
+ z[j++] = '?';
+ break;
+ }
+ }
+ if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){
+ z[j++] = ' ';
+ }
+ if( tokenType==TK_ID ){
+ int i2 = i, n2 = n, rc = SQLITE_OK;
+ if( nParen>0 ){
+ assert( nParen0 && z[j-1]==' ' ){ j--; }
+ if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; }
+ z[j] = 0;
+ assert( jzNormSql = z;
+ sqlite3HashClear(&inHash);
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
/*
** Rerun the compilation of a statement after a schema change.
**
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
** if the statement cannot be recompiled because another connection has
@@ -123929,11 +124708,11 @@
ExprList *pExtra = 0;
for(i=0; inExpr; i++){
struct ExprList_item *pItem = &pEList->a[i];
if( pItem->u.x.iOrderByCol==0 ){
Expr *pExpr = pItem->pExpr;
- Table *pTab = pExpr->pTab;
+ Table *pTab = pExpr->y.pTab;
if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
&& (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
){
int j;
for(j=0; jiTable = pExpr->iTable;
- pNew->pTab = pExpr->pTab;
+ pNew->y.pTab = pExpr->y.pTab;
pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
}
}
- pSort->aDefer[nDefer].pTab = pExpr->pTab;
+ pSort->aDefer[nDefer].pTab = pExpr->y.pTab;
pSort->aDefer[nDefer].iCsr = pExpr->iTable;
pSort->aDefer[nDefer].nKey = nKey;
nDefer++;
}
}
@@ -124806,11 +125585,11 @@
** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
** branch below. */
break;
}
- assert( pTab && pExpr->pTab==pTab );
+ assert( pTab && pExpr->y.pTab==pTab );
if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
@@ -124991,19 +125770,19 @@
for(i=0; inExpr; i++){
Expr *p = pEList->a[i].pExpr;
assert( p!=0 );
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
- assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
+ assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
if( pEList->a[i].zName ){
/* An AS clause always takes first priority */
char *zName = pEList->a[i].zName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
}else if( srcName && p->op==TK_COLUMN ){
char *zCol;
int iCol = p->iColumn;
- pTab = p->pTab;
+ pTab = p->y.pTab;
assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iColnCol) );
if( iCol<0 ){
zCol = "rowid";
@@ -125090,11 +125869,11 @@
}
assert( pColExpr->op!=TK_AGG_COLUMN );
if( pColExpr->op==TK_COLUMN ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
- Table *pTab = pColExpr->pTab;
+ Table *pTab = pColExpr->y.pTab;
assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
}else if( pColExpr->op==TK_ID ){
assert( !ExprHasProperty(pColExpr, EP_IntValue) );
@@ -131214,10 +131993,61 @@
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
}
+
+/*
+** Check to see if column iCol of index pIdx references any of the
+** columns defined by aXRef and chngRowid. Return true if it does
+** and false if not. This is an optimization. False-positives are a
+** performance degradation, but false-negatives can result in a corrupt
+** index and incorrect answers.
+**
+** aXRef[j] will be non-negative if column j of the original table is
+** being updated. chngRowid will be true if the rowid of the table is
+** being updated.
+*/
+static int indexColumnIsBeingUpdated(
+ Index *pIdx, /* The index to check */
+ int iCol, /* Which column of the index to check */
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
+ int chngRowid /* true if the rowid is being updated */
+){
+ i16 iIdxCol = pIdx->aiColumn[iCol];
+ assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */
+ if( iIdxCol>=0 ){
+ return aXRef[iIdxCol]>=0;
+ }
+ assert( iIdxCol==XN_EXPR );
+ assert( pIdx->aColExpr!=0 );
+ assert( pIdx->aColExpr->a[iCol].pExpr!=0 );
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr,
+ aXRef,chngRowid);
+}
+
+/*
+** Check to see if index pIdx is a partial index whose conditional
+** expression might change values due to an UPDATE. Return true if
+** the index is subject to change and false if the index is guaranteed
+** to be unchanged. This is an optimization. False-positives are a
+** performance degradation, but false-negatives can result in a corrupt
+** index and incorrect answers.
+**
+** aXRef[j] will be non-negative if column j of the original table is
+** being updated. chngRowid will be true if the rowid of the table is
+** being updated.
+*/
+static int indexWhereClauseMightChange(
+ Index *pIdx, /* The index to check */
+ int *aXRef, /* aXRef[j]>=0 if column j is being updated */
+ int chngRowid /* true if the rowid is being updated */
+){
+ if( pIdx->pPartIdxWhere==0 ) return 0;
+ return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere,
+ aXRef, chngRowid);
+}
/*
** Process an UPDATE statement.
**
** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
@@ -131438,23 +132268,22 @@
hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
/* There is one entry in the aRegIdx[] array for each index on the table
** being updated. Fill in aRegIdx[] with a register number that will hold
** the key for accessing each index.
- **
- ** FIXME: Be smarter about omitting indexes that use expressions.
*/
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
- if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){
+ if( chngKey || hasFK>1 || pIdx==pPk
+ || indexWhereClauseMightChange(pIdx,aXRef,chngRowid)
+ ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
}else{
reg = 0;
for(i=0; inKeyCol; i++){
- i16 iIdxCol = pIdx->aiColumn[i];
- if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
+ if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){
reg = ++pParse->nMem;
pParse->nMem += pIdx->nColumn;
if( (onError==OE_Replace)
|| (onError==OE_Default && pIdx->onError==OE_Replace)
){
@@ -132500,11 +133329,12 @@
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_mTrace = db->mTrace;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
- db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
+ db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder
+ | SQLITE_Defensive | SQLITE_CountRows);
db->mTrace = 0;
zDbMain = db->aDb[iDb].zDbSName;
pMain = db->aDb[iDb].pBt;
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
@@ -133042,22 +133872,19 @@
Token *pName1, /* Name of new table, or database name */
Token *pName2, /* Name of new table or NULL */
Token *pModuleName, /* Name of the module for the virtual table */
int ifNotExists /* No error if the table already exists */
){
- int iDb; /* The database the table is being created in */
Table *pTable; /* The new virtual table */
sqlite3 *db; /* Database connection */
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists);
pTable = pParse->pNewTable;
if( pTable==0 ) return;
assert( 0==pTable->pIndex );
db = pParse->db;
- iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
- assert( iDb>=0 );
assert( pTable->nModuleArg==0 );
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(db, pTable, 0);
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
@@ -133073,10 +133900,12 @@
** The first invocation, to obtain permission to INSERT a row into the
** sqlite_master table, has already been made by sqlite3StartTable().
** The second call, to obtain permission to create the table, is made now.
*/
if( pTable->azModuleArg ){
+ int iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
+ assert( iDb>=0 ); /* The database the table is being created in */
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
}
#endif
}
@@ -133767,11 +134596,11 @@
int rc = 0;
/* Check to see the left operand is a column in a virtual table */
if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
- pTab = pExpr->pTab;
+ pTab = pExpr->y.pTab;
if( pTab==0 ) return pDef;
if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
@@ -134387,15 +135216,36 @@
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
int nRecValid; /* Number of valid fields currently in pRec */
#endif
unsigned int bldFlags; /* SQLITE_BLDF_* flags */
+ unsigned int iPlanLimit; /* Search limiter */
};
/* Allowed values for WhereLoopBuider.bldFlags */
#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
+
+/* The WhereLoopBuilder.iPlanLimit is used to limit the number of
+** index+constraint combinations the query planner will consider for a
+** particular query. If this parameter is unlimited, then certain
+** pathological queries can spend excess time in the sqlite3WhereBegin()
+** routine. The limit is high enough that is should not impact real-world
+** queries.
+**
+** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is
+** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM
+** clause is processed, so that every table in a join is guaranteed to be
+** able to propose a some index+constraint combinations even if the initial
+** baseline limit was exhausted by prior tables of the join.
+*/
+#ifndef SQLITE_QUERY_PLANNER_LIMIT
+# define SQLITE_QUERY_PLANNER_LIMIT 20000
+#endif
+#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR
+# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000
+#endif
/*
** The WHERE clause processing routine has two halves. The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop. An instance of
@@ -135646,11 +136496,11 @@
IdxExprTrans *pX = p->u.pIdxTrans;
if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){
pExpr->op = TK_COLUMN;
pExpr->iTable = pX->iIdxCur;
pExpr->iColumn = pX->iIdxCol;
- pExpr->pTab = 0;
+ pExpr->y.pTab = 0;
return WRC_Prune;
}else{
return WRC_Continue;
}
}
@@ -137046,11 +137896,11 @@
|| zNew[0]=='-'
|| (zNew[0]+1=='0' && iTo==1)
){
if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
+ || IsVirtual(pLeft->y.pTab) /* Value might be numeric */
){
sqlite3ExprDelete(db, pPrefix);
sqlite3ValueFree(pVal);
return 0;
}
@@ -137147,11 +137997,11 @@
**
** vtab_column MATCH expression
** MATCH(expression,vtab_column)
*/
pCol = pList->a[1].pExpr;
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
for(i=0; iu.zToken, aOp[i].zOp)==0 ){
*peOp2 = aOp[i].eOp2;
*ppRight = pList->a[0].pExpr;
*ppLeft = pCol;
@@ -137169,16 +138019,16 @@
** Historically, xFindFunction expected to see lower-case function
** names. But for this use case, xFindFunction is expected to deal
** with function names in an arbitrary case.
*/
pCol = pList->a[0].pExpr;
- if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){
+ if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){
sqlite3_vtab *pVtab;
sqlite3_module *pMod;
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
void *pNotUsed;
- pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab;
+ pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
pMod = (sqlite3_module *)pVtab->pModule;
if( pMod->xFindFunction!=0 ){
i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
@@ -137192,14 +138042,14 @@
}
}else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
int res = 0;
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
- if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
+ if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){
res++;
}
- if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
+ if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){
res++;
SWAP(Expr*, pLeft, pRight);
}
*ppLeft = pLeft;
*ppRight = pRight;
@@ -138339,10 +139189,11 @@
pTab = pItem->pTab;
assert( pTab!=0 );
pArgs = pItem->u1.pFuncArg;
if( pArgs==0 ) return;
for(j=k=0; jnExpr; j++){
+ Expr *pRhs;
while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
if( k>=pTab->nCol ){
sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
pTab->zName, j);
return;
@@ -138349,13 +139200,14 @@
}
pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
if( pColRef==0 ) return;
pColRef->iTable = pItem->iCursor;
pColRef->iColumn = k++;
- pColRef->pTab = pTab;
- pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
- sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
+ pColRef->y.pTab = pTab;
+ pRhs = sqlite3PExpr(pParse, TK_UPLUS,
+ sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
+ pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
}
}
/************** End of whereexpr.c *******************************************/
@@ -139214,11 +140066,10 @@
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
testcase( pParse->db->mallocFailed );
translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
pTabItem->regResult, 1);
sqlite3VdbeGoto(v, addrTop);
- pTabItem->fg.viaCoroutine = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
}
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
@@ -139392,13 +140243,15 @@
** The table object reference passed as the second argument to this function
** must represent a virtual table. This function invokes the xBestIndex()
** method of the virtual table with the sqlite3_index_info object that
** comes in as the 3rd argument to this function.
**
-** If an error occurs, pParse is populated with an error message and a
-** non-zero value is returned. Otherwise, 0 is returned and the output
-** part of the sqlite3_index_info structure is left populated.
+** If an error occurs, pParse is populated with an error message and an
+** appropriate error code is returned. A return of SQLITE_CONSTRAINT from
+** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that
+** the current configuration of "unusable" flags in sqlite3_index_info can
+** not result in a valid plan.
**
** Whether or not an error is returned, it is the responsibility of the
** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates
** that this is required.
*/
@@ -139408,11 +140261,11 @@
TRACE_IDX_INPUTS(p);
rc = pVtab->pModule->xBestIndex(pVtab, p);
TRACE_IDX_OUTPUTS(p);
- if( rc!=SQLITE_OK ){
+ if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){
if( rc==SQLITE_NOMEM ){
sqlite3OomFault(pParse->db);
}else if( !pVtab->zErrMsg ){
sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc));
}else{
@@ -139419,23 +140272,11 @@
sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
}
}
sqlite3_free(pVtab->zErrMsg);
pVtab->zErrMsg = 0;
-
-#if 0
- /* This error is now caught by the caller.
- ** Search for "xBestIndex malfunction" below */
- for(i=0; inConstraint; i++){
- if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){
- sqlite3ErrorMsg(pParse,
- "table %s: xBestIndex returned an invalid plan", pTab->zName);
- }
- }
-#endif
-
- return pParse->nErr;
+ return rc;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
@@ -140485,10 +141326,18 @@
static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
WhereLoop **ppPrev, *p;
WhereInfo *pWInfo = pBuilder->pWInfo;
sqlite3 *db = pWInfo->pParse->db;
int rc;
+
+ /* Stop the search once we hit the query planner search limit */
+ if( pBuilder->iPlanLimit==0 ){
+ WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n"));
+ if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0;
+ return SQLITE_DONE;
+ }
+ pBuilder->iPlanLimit--;
/* If pBuilder->pOrSet is defined, then only keep track of the costs
** and prereqs.
*/
if( pBuilder->pOrSet!=0 ){
@@ -141496,11 +142345,21 @@
pIdxInfo->idxFlags = 0;
pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed;
/* Invoke the virtual table xBestIndex() method */
rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo);
- if( rc ) return rc;
+ if( rc ){
+ if( rc==SQLITE_CONSTRAINT ){
+ /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means
+ ** that the particular combination of parameters provided is unusable.
+ ** Make no entries in the loop table.
+ */
+ WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n"));
+ return SQLITE_OK;
+ }
+ return rc;
+ }
mxTerm = -1;
assert( pNew->nLSlot>=nConstraint );
for(i=0; iaLTerm[i] = 0;
pNew->u.vtab.omitMask = 0;
@@ -141892,13 +142751,15 @@
u8 priorJointype = 0;
/* Loop over the tables in the join, from left to right */
pNew = pBuilder->pNew;
whereLoopInit(pNew);
+ pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT;
for(iTab=0, pItem=pTabList->a; pItemiTab = iTab;
+ pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){
/* This condition is true when pItem is the FROM clause term on the
** right-hand-side of a LEFT or CROSS JOIN. */
mPrereq = mPrior;
@@ -141920,11 +142781,19 @@
}
if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){
rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable);
}
mPrior |= pNew->maskSelf;
- if( rc || db->mallocFailed ) break;
+ if( rc || db->mallocFailed ){
+ if( rc==SQLITE_DONE ){
+ /* We hit the query planner search limit set by iPlanLimit */
+ sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search");
+ rc = SQLITE_OK;
+ }else{
+ break;
+ }
+ }
}
whereLoopClear(db, pNew);
return rc;
}
@@ -144302,16 +145171,16 @@
}
switch( pExpr->op ){
case TK_FUNCTION:
- if( pExpr->pWin==0 ){
+ if( !ExprHasProperty(pExpr, EP_WinFunc) ){
break;
}else{
Window *pWin;
for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){
- if( pExpr->pWin==pWin ){
+ if( pExpr->y.pWin==pWin ){
assert( pWin->pOwner==pExpr );
return WRC_Prune;
}
}
}
@@ -144424,11 +145293,11 @@
** are invoked in the correct order as described under "SELECT REWRITING"
** at the top of this file.
*/
SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
int rc = SQLITE_OK;
- if( p->pWin ){
+ if( p->pWin && p->pPrior==0 ){
Vdbe *v = sqlite3GetVdbe(pParse);
sqlite3 *db = pParse->db;
Select *pSub = 0; /* The subquery */
SrcList *pSrc = p->pSrc;
Expr *pWhere = p->pWhere;
@@ -144637,15 +145506,17 @@
/*
** Attach window object pWin to expression p.
*/
SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
if( p ){
+ assert( p->op==TK_FUNCTION );
/* This routine is only called for the parser. If pWin was not
** allocated due to an OOM, then the parser would fail before ever
** invoking this routine */
if( ALWAYS(pWin) ){
- p->pWin = pWin;
+ p->y.pWin = pWin;
+ ExprSetProperty(p, EP_WinFunc);
pWin->pOwner = p;
if( p->flags & EP_Distinct ){
sqlite3ErrorMsg(pParse,
"DISTINCT is not supported for window functions");
}
@@ -145804,11 +146675,11 @@
** third argument. Set the Window.pOwner field of the new object to
** pOwner.
*/
SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
Window *pNew = 0;
- if( p ){
+ if( ALWAYS(p) ){
pNew = sqlite3DbMallocZero(db, sizeof(Window));
if( pNew ){
pNew->zName = sqlite3DbStrDup(db, p->zName);
pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
@@ -145956,10 +146827,11 @@
**
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
/* #include */
+/* #include */
/************ Begin %include sections from the grammar ************************/
/* #include "sqliteInt.h" */
/*
@@ -146057,17 +146929,14 @@
p->flags = EP_Leaf;
p->iAgg = -1;
p->pLeft = p->pRight = 0;
p->x.pList = 0;
p->pAggInfo = 0;
- p->pTab = 0;
+ p->y.pTab = 0;
p->op2 = 0;
p->iTable = 0;
p->iColumn = 0;
-#ifndef SQLITE_OMIT_WINDOWFUNC
- p->pWin = 0;
-#endif
p->u.zToken = (char*)&p[1];
memcpy(p->u.zToken, t.z, t.n);
p->u.zToken[t.n] = 0;
if( sqlite3Isquote(p->u.zToken[0]) ){
if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
@@ -150255,14 +151124,13 @@
#endif
yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
yymajor = YYNOCODE;
}else{
while( yypParser->yytos >= yypParser->yystack
- && yymx != YYERRORSYMBOL
&& (yyact = yy_find_reduce_action(
yypParser->yytos->stateno,
- YYERRORSYMBOL)) >= YY_MIN_REDUCE
+ YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
){
yy_pop_parser_stack(yypParser);
}
if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
@@ -151225,10 +152093,77 @@
while( IdChar(z[i]) ){ i++; }
*tokenType = TK_ID;
return i;
}
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Return the length (in bytes) of the token that begins at z[0].
+** Store the token type in *tokenType before returning. If flags has
+** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type
+** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was
+** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags
+** if the token was recognized as a keyword; this is useful when the
+** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller
+** to differentiate between a keyword being treated as an identifier
+** (for normalization purposes) and an actual identifier.
+*/
+SQLITE_PRIVATE int sqlite3GetTokenNormalized(
+ const unsigned char *z,
+ int *tokenType,
+ int *flags
+){
+ int n;
+ unsigned char iClass = aiClass[*z];
+ if( iClass==CC_KYWD ){
+ int i;
+ for(i=1; aiClass[z[i]]<=CC_KYWD; i++){}
+ if( IdChar(z[i]) ){
+ /* This token started out using characters that can appear in keywords,
+ ** but z[i] is a character not allowed within keywords, so this must
+ ** be an identifier instead */
+ i++;
+ while( IdChar(z[i]) ){ i++; }
+ *tokenType = TK_ID;
+ return i;
+ }
+ *tokenType = TK_ID;
+ n = keywordCode((char*)z, i, tokenType);
+ /* If the token is no longer considered to be an identifier, then it is a
+ ** keyword of some kind. Make the token back into an identifier and then
+ ** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are
+ ** used verbatim, including IN, IS, NOT, and NULL. */
+ switch( *tokenType ){
+ case TK_ID: {
+ /* do nothing, handled by caller */
+ break;
+ }
+ case TK_IN:
+ case TK_IS:
+ case TK_NOT:
+ case TK_NULL: {
+ *flags |= SQLITE_TOKEN_KEYWORD;
+ break;
+ }
+ default: {
+ *tokenType = TK_ID;
+ *flags |= SQLITE_TOKEN_KEYWORD;
+ break;
+ }
+ }
+ }else{
+ n = sqlite3GetToken(z, tokenType);
+ /* If the token is considered to be an identifier and the character class
+ ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */
+ if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){
+ *flags |= SQLITE_TOKEN_QUOTED;
+ }
+ }
+ return n;
+}
+#endif /* SQLITE_ENABLE_NORMALIZE */
+
/*
** Run the parser on the given SQL string. The parser structure is
** passed in. An SQLITE_ status code is returned. If an error occurs
** then an and attempt is made to write an error message into
** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
@@ -152622,10 +153557,11 @@
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
{ SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
+ { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
for(i=0; iaCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3HashInit(&db->aModule);
#endif
@@ -155736,18 +156675,29 @@
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
**
- ** If parameter onoff is non-zero, configure the wrappers so that all
- ** subsequent calls to localtime() and variants fail. If onoff is zero,
- ** undo this setting.
+ ** If parameter onoff is non-zero, subsequent calls to localtime()
+ ** and its variants fail. If onoff is zero, undo this setting.
*/
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
break;
}
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
+ **
+ ** If parameter onoff is non-zero, internal-use-only SQL functions
+ ** are visible to ordinary SQL. This is useful for testing but is
+ ** unsafe because invalid parameters to those internal-use-only functions
+ ** can result in crashes or segfaults.
+ */
+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
+ sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
+ break;
+ }
/* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
**
** Set or clear a flag that indicates that the database file is always well-
** formed and never corrupt. This flag is clear by default, indicating that
@@ -161211,13 +162161,28 @@
assert( p->mxSavepoint >= iSavepoint );
TESTONLY( p->mxSavepoint = iSavepoint );
sqlite3Fts3PendingTermsClear(p);
return SQLITE_OK;
}
+
+/*
+** Return true if zName is the extension on one of the shadow tables used
+** by this module.
+*/
+static int fts3ShadowName(const char *zName){
+ static const char *azName[] = {
+ "content", "docsize", "segdir", "segments", "stat",
+ };
+ unsigned int i;
+ for(i=0; iaConstraint;
for(i=0; inConstraint; i++, pConstraint++){
- if( pConstraint->usable==0 ) continue;
- if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
- switch( pConstraint->iColumn ){
- case JEACH_JSON: jsonIdx = i; break;
- case JEACH_ROOT: rootIdx = i; break;
- default: /* no-op */ break;
+ int iCol;
+ int iMask;
+ if( pConstraint->iColumn < JEACH_JSON ) continue;
+ iCol = pConstraint->iColumn - JEACH_JSON;
+ assert( iCol==0 || iCol==1 );
+ iMask = 1 << iCol;
+ if( pConstraint->usable==0 ){
+ unusableMask |= iMask;
+ }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ aIdx[iCol] = i;
+ idxMask |= iMask;
}
}
- if( jsonIdx<0 ){
+ if( (unusableMask & ~idxMask)!=0 ){
+ /* If there are any unusable constraints on JSON or ROOT, then reject
+ ** this entire plan */
+ return SQLITE_CONSTRAINT;
+ }
+ if( aIdx[0]<0 ){
+ /* No JSON input. Leave estimatedCost at the huge value that it was
+ ** initialized to to discourage the query planner from selecting this
+ ** plan. */
pIdxInfo->idxNum = 0;
- pIdxInfo->estimatedCost = 1e99;
}else{
pIdxInfo->estimatedCost = 1.0;
- pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1;
- pIdxInfo->aConstraintUsage[jsonIdx].omit = 1;
- if( rootIdx<0 ){
- pIdxInfo->idxNum = 1;
+ i = aIdx[0];
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ if( aIdx[1]<0 ){
+ pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */
}else{
- pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2;
- pIdxInfo->aConstraintUsage[rootIdx].omit = 1;
- pIdxInfo->idxNum = 3;
+ i = aIdx[1];
+ pIdxInfo->aConstraintUsage[i].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */
}
}
return SQLITE_OK;
}
@@ -177997,11 +178989,12 @@
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
/* The methods of the json_tree virtual table. */
static sqlite3_module jsonTreeModule = {
0, /* iVersion */
@@ -178024,11 +179017,12 @@
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
+ 0 /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
/****************************************************************************
** The following routines are the only publically visible identifiers in this
@@ -181454,12 +182448,28 @@
}
return rc;
}
+
+/*
+** Return true if zName is the extension on one of the shadow tables used
+** by this module.
+*/
+static int rtreeShadowName(const char *zName){
+ static const char *azName[] = {
+ "node", "parent", "rowid"
+ };
+ unsigned int i;
+ for(i=0; iz[0] && safe_isspace(p->z[0]) ) p->z++;
+ while( safe_isspace(p->z[0]) ) p->z++;
return p->z[0];
}
/* Parse out a number. Write the value into *pVal if pVal!=0.
** return non-zero on success and zero if the next token is not a number.
@@ -182520,11 +183541,11 @@
c = z[j];
}
if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
for(;; j++){
c = z[j];
- if( c>='0' && c<='9' ) continue;
+ if( safe_isdigit(c) ) continue;
if( c=='.' ){
if( z[j-1]=='-' ) return 0;
if( seenDP ) return 0;
seenDP = 1;
continue;
@@ -182542,11 +183563,21 @@
continue;
}
break;
}
if( z[j-1]<'0' ) return 0;
- if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z);
+ if( pVal ){
+#ifdef SQLITE_AMALGAMATION
+ /* The sqlite3AtoF() routine is much much faster than atof(), if it
+ ** is available */
+ double r;
+ (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8);
+ *pVal = r;
+#else
+ *pVal = (GeoCoord)atof((const char*)p->z);
+#endif
+ }
p->z += j;
return 1;
}
/*
@@ -182600,16 +183631,14 @@
&& s.nVertex>=4
&& s.a[0]==s.a[s.nVertex*2-2]
&& s.a[1]==s.a[s.nVertex*2-1]
&& (s.z++, geopolySkipSpace(&s)==0)
){
- int nByte;
GeoPoly *pOut;
int x = 1;
s.nVertex--; /* Remove the redundant vertex at the end */
- nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
- pOut = sqlite3_malloc64( nByte );
+ pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
x = 1;
if( pOut==0 ) goto parse_json_err;
pOut->nVertex = s.nVertex;
memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
pOut->hdr[0] = *(unsigned char*)&x;
@@ -182807,10 +183836,31 @@
sqlite3_result_blob(context, p->hdr,
4+8*p->nVertex, SQLITE_TRANSIENT);
sqlite3_free(p);
}
}
+
+/*
+** Compute the area enclosed by the polygon.
+**
+** This routine can also be used to detect polygons that rotate in
+** the wrong direction. Polygons are suppose to be counter-clockwise (CCW).
+** This routine returns a negative value for clockwise (CW) polygons.
+*/
+static double geopolyArea(GeoPoly *p){
+ double rArea = 0.0;
+ int ii;
+ for(ii=0; iinVertex-1; ii++){
+ rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
+ * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
+ * 0.5;
+ }
+ rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
+ * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
+ * 0.5;
+ return rArea;
+}
/*
** Implementation of the geopoly_area(X) function.
**
** If the input is a well-formed Geopoly BLOB then return the area
@@ -182823,24 +183873,109 @@
int argc,
sqlite3_value **argv
){
GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
if( p ){
- double rArea = 0.0;
- int ii;
- for(ii=0; iinVertex-1; ii++){
- rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
- * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
- * 0.5;
- }
- rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
- * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
- * 0.5;
- sqlite3_result_double(context, rArea);
+ sqlite3_result_double(context, geopolyArea(p));
+ sqlite3_free(p);
+ }
+}
+
+/*
+** Implementation of the geopoly_ccw(X) function.
+**
+** If the rotation of polygon X is clockwise (incorrect) instead of
+** counter-clockwise (the correct winding order according to RFC7946)
+** then reverse the order of the vertexes in polygon X.
+**
+** In other words, this routine returns a CCW polygon regardless of the
+** winding order of its input.
+**
+** Use this routine to sanitize historical inputs that that sometimes
+** contain polygons that wind in the wrong direction.
+*/
+static void geopolyCcwFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+ if( p ){
+ if( geopolyArea(p)<0.0 ){
+ int ii, jj;
+ for(ii=2, jj=p->nVertex*2 - 2; iia[ii];
+ p->a[ii] = p->a[jj];
+ p->a[jj] = t;
+ t = p->a[ii+1];
+ p->a[ii+1] = p->a[jj+1];
+ p->a[jj+1] = t;
+ }
+ }
+ sqlite3_result_blob(context, p->hdr,
+ 4+8*p->nVertex, SQLITE_TRANSIENT);
sqlite3_free(p);
}
}
+
+#define GEOPOLY_PI 3.1415926535897932385
+
+/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
+*/
+static double geopolySine(double r){
+ assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
+ if( r>=1.5*GEOPOLY_PI ){
+ r -= 2.0*GEOPOLY_PI;
+ }
+ if( r>=0.5*GEOPOLY_PI ){
+ return -geopolySine(r-GEOPOLY_PI);
+ }else{
+ double r2 = r*r;
+ double r3 = r2*r;
+ double r5 = r3*r2;
+ return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
+ }
+}
+
+/*
+** Function: geopoly_regular(X,Y,R,N)
+**
+** Construct a simple, convex, regular polygon centered at X, Y
+** with circumradius R and with N sides.
+*/
+static void geopolyRegularFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ double x = sqlite3_value_double(argv[0]);
+ double y = sqlite3_value_double(argv[1]);
+ double r = sqlite3_value_double(argv[2]);
+ int n = sqlite3_value_int(argv[3]);
+ int i;
+ GeoPoly *p;
+
+ if( n<3 || r<=0.0 ) return;
+ if( n>1000 ) n = 1000;
+ p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) );
+ if( p==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+ i = 1;
+ p->hdr[0] = *(unsigned char*)&i;
+ p->hdr[1] = 0;
+ p->hdr[2] = (n>>8)&0xff;
+ p->hdr[3] = n&0xff;
+ for(i=0; ia[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
+ p->a[i*2+1] = y + r*geopolySine(rAngle);
+ }
+ sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
+ sqlite3_free(p);
+}
/*
** If pPoly is a polygon, compute its bounding box. Then:
**
** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL
@@ -182882,11 +184017,11 @@
else if( r>mxY ) mxY = (float)r;
}
if( pRc ) *pRc = SQLITE_OK;
if( aCoord==0 ){
geopolyBboxFill:
- pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6);
+ pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
if( pOut==0 ){
sqlite3_free(p);
if( context ) sqlite3_result_error_nomem(context);
if( pRc ) *pRc = SQLITE_NOMEM;
return 0;
@@ -183910,11 +185045,20 @@
sqlite3_bind_int64(pUp, 1, cell.iRowid);
assert( pRtree->nAux>=1 );
if( sqlite3_value_nochange(aData[2]) ){
sqlite3_bind_null(pUp, 2);
}else{
- sqlite3_bind_value(pUp, 2, aData[2]);
+ GeoPoly *p = 0;
+ if( sqlite3_value_type(aData[2])==SQLITE_TEXT
+ && (p = geopolyFuncParam(0, aData[2], &rc))!=0
+ && rc==SQLITE_OK
+ ){
+ sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_bind_value(pUp, 2, aData[2]);
+ }
+ sqlite3_free(p);
nChange = 1;
}
for(jj=1; jjnAux; jj++){
nChange++;
sqlite3_bind_value(pUp, jj+2, aData[jj+2]);
@@ -183954,11 +185098,11 @@
return 0;
}
static sqlite3_module geopolyModule = {
- 2, /* iVersion */
+ 3, /* iVersion */
geopolyCreate, /* xCreate - create a table */
geopolyConnect, /* xConnect - connect to an existing table */
geopolyBestIndex, /* xBestIndex - Determine search strategy */
rtreeDisconnect, /* xDisconnect - Disconnect from a table */
rtreeDestroy, /* xDestroy - Drop a table */
@@ -183977,29 +185121,33 @@
geopolyFindFunction, /* xFindFunction - function overloading */
rtreeRename, /* xRename - rename the table */
rtreeSavepoint, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
+ rtreeShadowName /* xShadowName */
};
static int sqlite3_geopoly_init(sqlite3 *db){
int rc = SQLITE_OK;
static const struct {
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
- int nArg;
+ signed char nArg;
+ unsigned char bPure;
const char *zName;
} aFunc[] = {
- { geopolyAreaFunc, 1, "geopoly_area" },
- { geopolyBlobFunc, 1, "geopoly_blob" },
- { geopolyJsonFunc, 1, "geopoly_json" },
- { geopolySvgFunc, -1, "geopoly_svg" },
- { geopolyWithinFunc, 2, "geopoly_within" },
- { geopolyContainsPointFunc, 3, "geopoly_contains_point" },
- { geopolyOverlapFunc, 2, "geopoly_overlap" },
- { geopolyDebugFunc, 1, "geopoly_debug" },
- { geopolyBBoxFunc, 1, "geopoly_bbox" },
- { geopolyXformFunc, 7, "geopoly_xform" },
+ { geopolyAreaFunc, 1, 1, "geopoly_area" },
+ { geopolyBlobFunc, 1, 1, "geopoly_blob" },
+ { geopolyJsonFunc, 1, 1, "geopoly_json" },
+ { geopolySvgFunc, -1, 1, "geopoly_svg" },
+ { geopolyWithinFunc, 2, 1, "geopoly_within" },
+ { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" },
+ { geopolyOverlapFunc, 2, 1, "geopoly_overlap" },
+ { geopolyDebugFunc, 1, 0, "geopoly_debug" },
+ { geopolyBBoxFunc, 1, 1, "geopoly_bbox" },
+ { geopolyXformFunc, 7, 1, "geopoly_xform" },
+ { geopolyRegularFunc, 4, 1, "geopoly_regular" },
+ { geopolyCcwFunc, 1, 1, "geopoly_ccw" },
};
static const struct {
void (*xStep)(sqlite3_context*,int,sqlite3_value**);
void (*xFinal)(sqlite3_context*);
const char *zName;
@@ -184006,12 +185154,13 @@
} aAgg[] = {
{ geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" },
};
int i;
for(i=0; isz = nNew;
assert( pRbu->szTemp>=0 );
if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
return SQLITE_OK;
}
+
+/*
+** Add an item to the main-db lists, if it is not already present.
+**
+** There are two main-db lists. One for all file descriptors, and one
+** for all file descriptors with rbu_file.pDb!=0. If the argument has
+** rbu_file.pDb!=0, then it is assumed to already be present on the
+** main list and is only added to the pDb!=0 list.
+*/
+static void rbuMainlistAdd(rbu_file *p){
+ rbu_vfs *pRbuVfs = p->pRbuVfs;
+ rbu_file *pIter;
+ assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) );
+ sqlite3_mutex_enter(pRbuVfs->mutex);
+ if( p->pRbu==0 ){
+ for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext);
+ p->pMainNext = pRbuVfs->pMain;
+ pRbuVfs->pMain = p;
+ }else{
+ for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){}
+ if( pIter==0 ){
+ p->pMainRbuNext = pRbuVfs->pMainRbu;
+ pRbuVfs->pMainRbu = p;
+ }
+ }
+ sqlite3_mutex_leave(pRbuVfs->mutex);
+}
+
+/*
+** Remove an item from the main-db lists.
+*/
+static void rbuMainlistRemove(rbu_file *p){
+ rbu_file **pp;
+ sqlite3_mutex_enter(p->pRbuVfs->mutex);
+ for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){}
+ if( *pp ) *pp = p->pMainNext;
+ p->pMainNext = 0;
+ for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){}
+ if( *pp ) *pp = p->pMainRbuNext;
+ p->pMainRbuNext = 0;
+ sqlite3_mutex_leave(p->pRbuVfs->mutex);
+}
+
+/*
+** Given that zWal points to a buffer containing a wal file name passed to
+** either the xOpen() or xAccess() VFS method, search the main-db list for
+** a file-handle opened by the same database connection on the corresponding
+** database file.
+**
+** If parameter bRbu is true, only search for file-descriptors with
+** rbu_file.pDb!=0.
+*/
+static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){
+ rbu_file *pDb;
+ sqlite3_mutex_enter(pRbuVfs->mutex);
+ if( bRbu ){
+ for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){}
+ }else{
+ for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
+ }
+ sqlite3_mutex_leave(pRbuVfs->mutex);
+ return pDb;
+}
/*
** Close an rbu file.
*/
static int rbuVfsClose(sqlite3_file *pFile){
@@ -189676,21 +190890,18 @@
sqlite3_free(p->apShm);
p->apShm = 0;
sqlite3_free(p->zDel);
if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
- rbu_file **pp;
- sqlite3_mutex_enter(p->pRbuVfs->mutex);
- for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
- *pp = p->pMainNext;
- sqlite3_mutex_leave(p->pRbuVfs->mutex);
+ rbuMainlistRemove(p);
rbuUnlockShm(p);
p->pReal->pMethods->xShmUnmap(p->pReal, 0);
}
else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
rbuUpdateTempSize(p, 0);
}
+ assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p );
/* Close the underlying file handle */
rc = p->pReal->pMethods->xClose(p->pReal);
return rc;
}
@@ -189945,10 +191156,13 @@
rc = SQLITE_ERROR;
pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error");
}else if( rc==SQLITE_NOTFOUND ){
pRbu->pTargetFd = p;
p->pRbu = pRbu;
+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
+ rbuMainlistAdd(p);
+ }
if( p->pWalFd ) p->pWalFd->pRbu = pRbu;
rc = SQLITE_OK;
}
}
return rc;
@@ -190106,24 +191320,10 @@
rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
}
return rc;
}
-/*
-** Given that zWal points to a buffer containing a wal file name passed to
-** either the xOpen() or xAccess() VFS method, return a pointer to the
-** file-handle opened by the same database connection on the corresponding
-** database file.
-*/
-static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
- rbu_file *pDb;
- sqlite3_mutex_enter(pRbuVfs->mutex);
- for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
- sqlite3_mutex_leave(pRbuVfs->mutex);
- return pDb;
-}
-
/*
** A main database named zName has just been opened. The following
** function returns a pointer to a buffer owned by SQLite that contains
** the name of the *-wal file this db connection will use. SQLite
** happens to pass a pointer to this buffer when using xAccess()
@@ -190198,11 +191398,11 @@
** happens to pass a pointer to this buffer when using xAccess()
** or xOpen() to operate on the *-wal file. */
pFd->zWal = rbuMainToWal(zName, flags);
}
else if( flags & SQLITE_OPEN_WAL ){
- rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName);
+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0);
if( pDb ){
if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
/* This call is to open a *-wal file. Intead, open the *-oal. This
** code ensures that the string passed to xOpen() is terminated by a
** pair of '\0' bytes in case the VFS attempts to extract a URI
@@ -190250,14 +191450,11 @@
/* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
** pointer and, if the file is a main database file, link it into the
** mutex protected linked list of all such files. */
pFile->pMethods = &rbuvfs_io_methods;
if( flags & SQLITE_OPEN_MAIN_DB ){
- sqlite3_mutex_enter(pRbuVfs->mutex);
- pFd->pMainNext = pRbuVfs->pMain;
- pRbuVfs->pMain = pFd;
- sqlite3_mutex_leave(pRbuVfs->mutex);
+ rbuMainlistAdd(pFd);
}
}else{
sqlite3_free(pFd->zDel);
}
@@ -190301,11 +191498,11 @@
** causing SQLite to call xOpen() to open it. This call will also
** be intercepted (see the rbuVfsOpen() function) and the *-oal
** file opened instead.
*/
if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
- rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath);
+ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1);
if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){
if( *pResOut ){
rc = SQLITE_CANTOPEN;
}else{
sqlite3_int64 sz = 0;
@@ -190714,21 +191911,19 @@
** idxNum is normally 0, but will be 1 if a schema=? constraint exists.
*/
static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
int i;
- pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */
-
/* Look for a valid schema=? constraint. If found, change the idxNum to
** 1 and request the value of that constraint be sent to xFilter. And
** lower the cost estimate to encourage the constrained version to be
** used.
*/
for(i=0; inConstraint; i++){
- if( pIdxInfo->aConstraint[i].usable==0 ) continue;
- if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue;
+ if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT;
+ if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
pIdxInfo->idxNum = 1;
pIdxInfo->estimatedCost = 1.0;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
break;
@@ -190774,18 +191969,24 @@
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
return SQLITE_OK;
}
-static void statClearPage(StatPage *p){
+static void statClearCells(StatPage *p){
int i;
if( p->aCell ){
for(i=0; inCell; i++){
sqlite3_free(p->aCell[i].aOvfl);
}
sqlite3_free(p->aCell);
}
+ p->nCell = 0;
+ p->aCell = 0;
+}
+
+static void statClearPage(StatPage *p){
+ statClearCells(p);
sqlite3PagerUnref(p->pPg);
sqlite3_free(p->zPath);
memset(p, 0, sizeof(StatPage));
}
@@ -190844,26 +192045,37 @@
u8 *aData = sqlite3PagerGetData(p->pPg);
u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
p->flags = aHdr[0];
+ if( p->flags==0x0A || p->flags==0x0D ){
+ isLeaf = 1;
+ nHdr = 8;
+ }else if( p->flags==0x05 || p->flags==0x02 ){
+ isLeaf = 0;
+ nHdr = 12;
+ }else{
+ goto statPageIsCorrupt;
+ }
+ if( p->iPgno==1 ) nHdr += 100;
p->nCell = get2byte(&aHdr[3]);
p->nMxPayload = 0;
-
- isLeaf = (p->flags==0x0A || p->flags==0x0D);
- nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
+ szPage = sqlite3BtreeGetPageSize(pBt);
nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
nUnused += (int)aHdr[7];
iOff = get2byte(&aHdr[1]);
while( iOff ){
+ int iNext;
+ if( iOff>=szPage ) goto statPageIsCorrupt;
nUnused += get2byte(&aData[iOff+2]);
- iOff = get2byte(&aData[iOff]);
+ iNext = get2byte(&aData[iOff]);
+ if( iNext0 ) goto statPageIsCorrupt;
+ iOff = iNext;
}
p->nUnused = nUnused;
p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
- szPage = sqlite3BtreeGetPageSize(pBt);
if( p->nCell ){
int i; /* Used to iterate through cells */
int nUsable; /* Usable bytes per page */
@@ -190876,10 +192088,11 @@
for(i=0; inCell; i++){
StatCell *pCell = &p->aCell[i];
iOff = get2byte(&aData[nHdr+i*2]);
+ if( iOff=szPage ) goto statPageIsCorrupt;
if( !isLeaf ){
pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
iOff += 4;
}
if( p->flags==0x05 ){
@@ -190892,17 +192105,18 @@
u64 dummy;
iOff += sqlite3GetVarint(&aData[iOff], &dummy);
}
if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
+ if( nLocal<0 ) goto statPageIsCorrupt;
pCell->nLocal = nLocal;
- assert( nLocal>=0 );
assert( nPayload>=(u32)nLocal );
assert( nLocal<=(nUsable-35) );
if( nPayload>(u32)nLocal ){
int j;
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
+ if( iOff+nLocal>nUsable ) goto statPageIsCorrupt;
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
pCell->nOvfl = nOvfl;
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
@@ -190922,10 +192136,15 @@
}
}
}
return SQLITE_OK;
+
+statPageIsCorrupt:
+ p->flags = 0;
+ statClearCells(p);
+ return SQLITE_OK;
}
/*
** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
** the current value of pCsr->iPageno.
@@ -191217,10 +192436,11 @@
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
+ 0 /* xShadowName */
};
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
}
#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191347,13 +192567,12 @@
for(i=0; inConstraint; i++){
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( !p->usable ){
- /* No solution. Use the default SQLITE_BIG_DBL cost */
- pIdxInfo->estimatedRows = 0x7fffffff;
- return SQLITE_OK;
+ /* No solution. */
+ return SQLITE_CONSTRAINT;
}
iPlan = 2;
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
pIdxInfo->aConstraintUsage[i].omit = 1;
break;
@@ -191541,10 +192760,14 @@
int iDb;
Btree *pBt;
Pager *pPager;
int szPage;
+ if( pTab->db->flags & SQLITE_Defensive ){
+ zErr = "read-only";
+ goto update_fail;
+ }
if( argc==1 ){
zErr = "cannot delete";
goto update_fail;
}
pgno = sqlite3_value_int(argv[0]);
@@ -191631,10 +192854,11 @@
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
+ 0 /* xShadowName */
};
return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
}
#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
@@ -191666,10 +192890,12 @@
# define SESSIONS_STRM_CHUNK_SIZE 64
# else
# define SESSIONS_STRM_CHUNK_SIZE 1024
# endif
#endif
+
+static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;
typedef struct SessionHook SessionHook;
struct SessionHook {
void *pCtx;
int (*xOld)(void*,int,sqlite3_value**);
@@ -191729,10 +192955,11 @@
*/
struct sqlite3_changeset_iter {
SessionInput in; /* Input buffer or stream */
SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */
int bPatchset; /* True if this is a patchset */
+ int bInvert; /* True to invert changeset */
int rc; /* Iterator error code */
sqlite3_stmt *pConflict; /* Points to conflicting row, if any */
char *zTab; /* Current table */
int nCol; /* Number of columns in zTab */
int op; /* Current operation */
@@ -191885,10 +193112,46 @@
** and fields associated with modified columns contain the new column values.
**
** The records associated with INSERT changes are in the same format as for
** changesets. It is not possible for a record associated with an INSERT
** change to contain a field set to "undefined".
+**
+** REBASE BLOB FORMAT:
+**
+** A rebase blob may be output by sqlite3changeset_apply_v2() and its
+** streaming equivalent for use with the sqlite3_rebaser APIs to rebase
+** existing changesets. A rebase blob contains one entry for each conflict
+** resolved using either the OMIT or REPLACE strategies within the apply_v2()
+** call.
+**
+** The format used for a rebase blob is very similar to that used for
+** changesets. All entries related to a single table are grouped together.
+**
+** Each group of entries begins with a table header in changeset format:
+**
+** 1 byte: Constant 0x54 (capital 'T')
+** Varint: Number of columns in the table.
+** nCol bytes: 0x01 for PK columns, 0x00 otherwise.
+** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated.
+**
+** Followed by one or more entries associated with the table.
+**
+** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09).
+** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT.
+** record: (in the record format defined above).
+**
+** In a rebase blob, the first field is set to SQLITE_INSERT if the change
+** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if
+** it was a DELETE. The second field is set to 0x01 if the conflict
+** resolution strategy was REPLACE, or 0x00 if it was OMIT.
+**
+** If the change that caused the conflict was a DELETE, then the single
+** record is a copy of the old.* record from the original changeset. If it
+** was an INSERT, then the single record is a copy of the new.* record. If
+** the conflicting change was an UPDATE, then the single record is a copy
+** of the new.* record with the PK fields filled in based on the original
+** old.* record.
*/
/*
** For each row modified during a session, there exists a single instance of
** this structure stored in a SessionTable.aChange[] hash table.
@@ -193435,16 +194698,16 @@
** set *pRc to SQLITE_NOMEM and return non-zero.
*/
static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
if( *pRc==SQLITE_OK && p->nAlloc-p->nBufnAlloc ? p->nAlloc : 128;
+ i64 nNew = p->nAlloc ? p->nAlloc : 128;
do {
nNew = nNew*2;
- }while( nNew<(p->nBuf+nByte) );
+ }while( (nNew-p->nBuf)aBuf, nNew);
+ aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew);
if( 0==aNew ){
*pRc = SQLITE_NOMEM;
}else{
p->aBuf = aNew;
p->nAlloc = nNew;
@@ -194038,16 +195301,16 @@
}
if( rc==SQLITE_OK ){
rc = sqlite3_reset(pSel);
}
- /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass
+ /* If the buffer is now larger than sessions_strm_chunk_size, pass
** its contents to the xOutput() callback. */
if( xOutput
&& rc==SQLITE_OK
&& buf.nBuf>nNoop
- && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE
+ && buf.nBuf>sessions_strm_chunk_size
){
rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf);
nNoop = -1;
buf.nBuf = 0;
}
@@ -194182,11 +195445,12 @@
static int sessionChangesetStart(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int nChangeset, /* Size of buffer pChangeset in bytes */
- void *pChangeset /* Pointer to buffer containing changeset */
+ void *pChangeset, /* Pointer to buffer containing changeset */
+ int bInvert /* True to invert changeset */
){
sqlite3_changeset_iter *pRet; /* Iterator to return */
int nByte; /* Number of bytes to allocate for iterator */
assert( xInput==0 || (pChangeset==0 && nChangeset==0) );
@@ -194202,10 +195466,11 @@
pRet->in.aData = (u8 *)pChangeset;
pRet->in.nData = nChangeset;
pRet->in.xInput = xInput;
pRet->in.pIn = pIn;
pRet->in.bEof = (xInput ? 0 : 1);
+ pRet->bInvert = bInvert;
/* Populate the output variable and return success. */
*pp = pRet;
return SQLITE_OK;
}
@@ -194216,11 +195481,20 @@
SQLITE_API int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int nChangeset, /* Size of buffer pChangeset in bytes */
void *pChangeset /* Pointer to buffer containing changeset */
){
- return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset);
+ return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0);
+}
+SQLITE_API int sqlite3changeset_start_v2(
+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
+ int nChangeset, /* Size of buffer pChangeset in bytes */
+ void *pChangeset, /* Pointer to buffer containing changeset */
+ int flags
+){
+ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
+ return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert);
}
/*
** Streaming version of sqlite3changeset_start().
*/
@@ -194227,19 +195501,28 @@
SQLITE_API int sqlite3changeset_start_strm(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
){
- return sessionChangesetStart(pp, xInput, pIn, 0, 0);
+ return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0);
+}
+SQLITE_API int sqlite3changeset_start_v2_strm(
+ sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int flags
+){
+ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT);
+ return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert);
}
/*
** If the SessionInput object passed as the only argument is a streaming
** object and the buffer is full, discard some data to free up space.
*/
static void sessionDiscardData(SessionInput *pIn){
- if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){
+ if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){
int nMove = pIn->buf.nBuf - pIn->iNext;
assert( nMove>=0 );
if( nMove>0 ){
memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove);
}
@@ -194258,11 +195541,11 @@
*/
static int sessionInputBuffer(SessionInput *pIn, int nByte){
int rc = SQLITE_OK;
if( pIn->xInput ){
while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){
- int nNew = SESSIONS_STRM_CHUNK_SIZE;
+ int nNew = sessions_strm_chunk_size;
if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn);
if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){
rc = pIn->xInput(pIn->pIn, &pIn->buf.aBuf[pIn->buf.nBuf], &nNew);
if( nNew==0 ){
@@ -194606,14 +195889,14 @@
p->in.iCurrent = p->in.iNext;
if( p->in.iNext>=p->in.nData ) return SQLITE_DONE;
op = p->in.aData[p->in.iNext++];
}
- if( p->zTab==0 ){
+ if( p->zTab==0 || (p->bPatchset && p->bInvert) ){
/* The first record in the changeset is not a table header. Must be a
** corrupt changeset. */
- assert( p->in.iNext==1 );
+ assert( p->in.iNext==1 || p->zTab );
return (p->rc = SQLITE_CORRUPT_BKPT);
}
p->op = op;
p->bIndirect = p->in.aData[p->in.iNext++];
@@ -194634,37 +195917,43 @@
p->rc = sessionChangesetBufferRecord(&p->in, nVal, pnRec);
if( p->rc!=SQLITE_OK ) return p->rc;
*paRec = &p->in.aData[p->in.iNext];
p->in.iNext += *pnRec;
}else{
+ sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue);
+ sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]);
/* If this is an UPDATE or DELETE, read the old.* record. */
if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){
u8 *abPK = p->bPatchset ? p->abPK : 0;
- p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue);
+ p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld);
if( p->rc!=SQLITE_OK ) return p->rc;
}
/* If this is an INSERT or UPDATE, read the new.* record. */
if( p->op!=SQLITE_DELETE ){
- p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]);
+ p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew);
if( p->rc!=SQLITE_OK ) return p->rc;
}
- if( p->bPatchset && p->op==SQLITE_UPDATE ){
+ if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){
/* If this is an UPDATE that is part of a patchset, then all PK and
** modified fields are present in the new.* record. The old.* record
** is currently completely empty. This block shifts the PK fields from
** new.* to old.*, to accommodate the code that reads these arrays. */
for(i=0; inCol; i++){
- assert( p->apValue[i]==0 );
+ assert( p->bPatchset==0 || p->apValue[i]==0 );
if( p->abPK[i] ){
+ assert( p->apValue[i]==0 );
p->apValue[i] = p->apValue[i+p->nCol];
if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT);
p->apValue[i+p->nCol] = 0;
}
}
+ }else if( p->bInvert ){
+ if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
+ else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
}
}
return SQLITE_ROW;
}
@@ -194977,11 +196266,11 @@
rc = SQLITE_CORRUPT_BKPT;
goto finished_invert;
}
assert( rc==SQLITE_OK );
- if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
+ if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
sOut.nBuf = 0;
if( rc!=SQLITE_OK ) goto finished_invert;
}
}
@@ -195056,11 +196345,12 @@
u8 *abPK; /* Boolean array - true if column is in PK */
int bStat1; /* True if table is sqlite_stat1 */
int bDeferConstraints; /* True to defer constraints */
SessionBuffer constraints; /* Deferred constraints are stored here */
SessionBuffer rebase; /* Rebase information (if any) here */
- int bRebaseStarted; /* If table header is already in rebase */
+ u8 bRebaseStarted; /* If table header is already in rebase */
+ u8 bRebase; /* True to collect rebase information */
};
/*
** Formulate a statement to DELETE a row from database db. Assuming a table
** structure like this:
@@ -195453,39 +196743,40 @@
SessionApplyCtx *p, /* Apply context */
int eType, /* Conflict resolution (OMIT or REPLACE) */
sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
){
int rc = SQLITE_OK;
- int i;
- int eOp = pIter->op;
- if( p->bRebaseStarted==0 ){
- /* Append a table-header to the rebase buffer */
- const char *zTab = pIter->zTab;
- sessionAppendByte(&p->rebase, 'T', &rc);
- sessionAppendVarint(&p->rebase, p->nCol, &rc);
- sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
- sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
- p->bRebaseStarted = 1;
- }
-
- assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
- assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
-
- sessionAppendByte(&p->rebase,
- (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
- );
- sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
- for(i=0; inCol; i++){
- sqlite3_value *pVal = 0;
- if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
- sqlite3changeset_old(pIter, i, &pVal);
- }else{
- sqlite3changeset_new(pIter, i, &pVal);
- }
- sessionAppendValue(&p->rebase, pVal, &rc);
- }
-
+ if( p->bRebase ){
+ int i;
+ int eOp = pIter->op;
+ if( p->bRebaseStarted==0 ){
+ /* Append a table-header to the rebase buffer */
+ const char *zTab = pIter->zTab;
+ sessionAppendByte(&p->rebase, 'T', &rc);
+ sessionAppendVarint(&p->rebase, p->nCol, &rc);
+ sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
+ sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
+ p->bRebaseStarted = 1;
+ }
+
+ assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
+ assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
+
+ sessionAppendByte(&p->rebase,
+ (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
+ );
+ sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
+ for(i=0; inCol; i++){
+ sqlite3_value *pVal = 0;
+ if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
+ sqlite3changeset_old(pIter, i, &pVal);
+ }else{
+ sqlite3changeset_new(pIter, i, &pVal);
+ }
+ sessionAppendValue(&p->rebase, pVal, &rc);
+ }
+ }
return rc;
}
/*
** Invoke the conflict handler for the change that the changeset iterator
@@ -195824,11 +197115,11 @@
while( pApply->constraints.nBuf ){
sqlite3_changeset_iter *pIter2 = 0;
SessionBuffer cons = pApply->constraints;
memset(&pApply->constraints, 0, sizeof(SessionBuffer));
- rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf);
+ rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
if( rc==SQLITE_OK ){
int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
int rc2;
pIter2->bPatchset = bPatchset;
pIter2->zTab = (char*)zTab;
@@ -195890,10 +197181,11 @@
assert( xConflict!=0 );
pIter->in.bNoDiscard = 1;
memset(&sApply, 0, sizeof(sApply));
+ sApply.bRebase = (ppRebase && pnRebase);
sqlite3_mutex_enter(sqlite3_db_mutex(db));
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
}
if( rc==SQLITE_OK ){
@@ -196040,11 +197332,12 @@
sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
}
}
- if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
+ assert( sApply.bRebase || sApply.rebase.nBuf==0 );
+ if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
*ppRebase = (void*)sApply.rebase.aBuf;
*pnRebase = sApply.rebase.nBuf;
sApply.rebase.aBuf = 0;
}
sqlite3_finalize(sApply.pInsert);
@@ -196078,11 +197371,12 @@
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
- int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
+ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
+ int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse);
if( rc==SQLITE_OK ){
rc = sessionChangesetApply(
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
);
}
@@ -196135,11 +197429,12 @@
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase,
int flags
){
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
- int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
+ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
+ int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse);
if( rc==SQLITE_OK ){
rc = sessionChangesetApply(
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
);
}
@@ -196508,17 +197803,16 @@
SessionChange *p;
for(p=pTab->apChange[i]; p; p=p->pNext){
sessionAppendByte(&buf, p->op, &rc);
sessionAppendByte(&buf, p->bIndirect, &rc);
sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc);
+ if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){
+ rc = xOutput(pOut, buf.aBuf, buf.nBuf);
+ buf.nBuf = 0;
+ }
}
}
-
- if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){
- rc = xOutput(pOut, buf.aBuf, buf.nBuf);
- buf.nBuf = 0;
- }
}
if( rc==SQLITE_OK ){
if( xOutput ){
if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
@@ -196905,11 +198199,11 @@
if( bDone==0 ){
sessionAppendByte(&sOut, pIter->op, &rc);
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
sessionAppendBlob(&sOut, aRec, nRec, &rc);
}
- if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
+ if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
sOut.nBuf = 0;
}
if( rc ) break;
}
@@ -197015,10 +198309,31 @@
if( p ){
sessionDeleteTable(p->grp.pList);
sqlite3_free(p);
}
}
+
+/*
+** Global configuration
+*/
+SQLITE_API int sqlite3session_config(int op, void *pArg){
+ int rc = SQLITE_OK;
+ switch( op ){
+ case SQLITE_SESSION_CONFIG_STRMSIZE: {
+ int *pInt = (int*)pArg;
+ if( *pInt>0 ){
+ sessions_strm_chunk_size = *pInt;
+ }
+ *pInt = sessions_strm_chunk_size;
+ break;
+ }
+ default:
+ rc = SQLITE_MISUSE;
+ break;
+ }
+ return rc;
+}
#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
/************** End of sqlite3session.c **************************************/
/************** Begin file fts5.c ********************************************/
@@ -198450,10 +199765,11 @@
**
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
/* #include */
+/* #include */
/************ Begin %include sections from the grammar ************************/
/* #include "fts5Int.h" */
/* #include "fts5parse.h" */
@@ -199777,14 +201093,13 @@
#endif
fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
fts5yymajor = fts5YYNOCODE;
}else{
while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
- && fts5yymx != fts5YYERRORSYMBOL
&& (fts5yyact = fts5yy_find_reduce_action(
fts5yypParser->fts5yytos->stateno,
- fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE
+ fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE
){
fts5yy_pop_parser_stack(fts5yypParser);
}
if( fts5yypParser->fts5yytos < fts5yypParser->fts5yystack || fts5yymajor==0 ){
fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion);
@@ -210730,11 +212045,11 @@
sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
pRet = 0;
fts5CloseReader(p);
}
- *ppIter = &pRet->base;
+ *ppIter = (Fts5IndexIter*)pRet;
sqlite3Fts5BufferFree(&buf);
}
return fts5IndexReturn(p);
}
@@ -214479,16 +215794,31 @@
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b75036f2", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT);
+}
+
+/*
+** Return true if zName is the extension on one of the shadow tables used
+** by this module.
+*/
+static int fts5ShadowName(const char *zName){
+ static const char *azName[] = {
+ "config", "content", "data", "docsize", "idx"
+ };
+ unsigned int i;
+ for(i=0; ipIter;
i64 *pp = &pCsr->iInstPos;
int *po = &pCsr->iInstOff;
+ assert( sqlite3Fts5IterEof(pIter)==0 );
+ assert( pCsr->bEof==0 );
while( eDetail==FTS5_DETAIL_NONE
|| sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
){
pCsr->iInstPos = 0;
pCsr->iInstOff = 0;
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
if( rc==SQLITE_OK ){
rc = fts5VocabInstanceNewTerm(pCsr);
- if( eDetail==FTS5_DETAIL_NONE ) break;
+ if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break;
}
if( rc ){
pCsr->bEof = 1;
break;
}
@@ -218875,17 +220208,16 @@
/* xFindFunction */ 0,
/* xRename */ 0,
/* xSavepoint */ 0,
/* xRelease */ 0,
/* xRollbackTo */ 0,
+ /* xShadowName */ 0
};
void *p = (void*)pGlobal;
return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
}
-
-
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
@@ -219157,10 +220489,11 @@
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
+ 0, /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */
SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){
@@ -219189,12 +220522,12 @@
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
-#if __LINE__!=219194
+#if __LINE__!=220527
#undef SQLITE_SOURCE_ID
-#define SQLITE_SOURCE_ID "2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b750alt2"
+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2"
#endif
/* Return the source-id for this library */
SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/************************** End of sqlite3.c ******************************/
Index: sqlite3/src/main/jni/sqlite/sqlite3.h
==================================================================
--- sqlite3/src/main/jni/sqlite/sqlite3.h
+++ sqlite3/src/main/jni/sqlite/sqlite3.h
@@ -121,13 +121,13 @@
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.25.3"
-#define SQLITE_VERSION_NUMBER 3025003
-#define SQLITE_SOURCE_ID "2018-11-05 20:37:38 89e099fbe5e13c33e683bef07361231ca525b88f7907be7092058007b75036f2"
+#define SQLITE_VERSION "3.26.0"
+#define SQLITE_VERSION_NUMBER 3026000
+#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
@@ -2015,10 +2015,11 @@
** the call worked. ^The [sqlite3_db_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
**
+** [[SQLITE_DBCONFIG_LOOKASIDE]]
** - SQLITE_DBCONFIG_LOOKASIDE
** - ^This option takes three additional arguments that determine the
** [lookaside memory allocator] configuration for the [database connection].
** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.
@@ -2037,10 +2038,11 @@
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].)^
**
+** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
** - SQLITE_DBCONFIG_ENABLE_FKEY
** - ^This option is used to enable or disable the enforcement of
** [foreign key constraints]. There should be two additional arguments.
** The first argument is an integer which is 0 to disable FK enforcement,
** positive to enable FK enforcement or negative to leave FK enforcement
@@ -2047,10 +2049,11 @@
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether FK enforcement is off or on
** following this call. The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back.
**
+** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]]
** - SQLITE_DBCONFIG_ENABLE_TRIGGER
** - ^This option is used to enable or disable [CREATE TRIGGER | triggers].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable triggers,
** positive to enable triggers or negative to leave the setting unchanged.
@@ -2057,10 +2060,11 @@
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether triggers are disabled or enabled
** following this call. The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back.
**
+** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
** - SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
** - ^This option is used to enable or disable the two-argument
** version of the [fts3_tokenizer()] function which is part of the
** [FTS3] full-text search engine extension.
** There should be two additional arguments.
@@ -2070,10 +2074,11 @@
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
** following this call. The second parameter may be a NULL pointer, in
** which case the new setting is not reported back.
**
+** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]]
** - SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
** - ^This option is used to enable or disable the [sqlite3_load_extension()]
** interface independently of the [load_extension()] SQL function.
** The [sqlite3_enable_load_extension()] API enables or disables both the
** C-API [sqlite3_load_extension()] and the SQL function [load_extension()].
@@ -2087,19 +2092,20 @@
** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface
** is disabled or enabled following this call. The second parameter may
** be a NULL pointer, in which case the new setting is not reported back.
**
**
-** - SQLITE_DBCONFIG_MAINDBNAME
+** [[SQLITE_DBCONFIG_MAINDBNAME]] - SQLITE_DBCONFIG_MAINDBNAME
** - ^This option is used to change the name of the "main" database
** schema. ^The sole argument is a pointer to a constant UTF8 string
** which will become the new schema name in place of "main". ^SQLite
** does not make a copy of the new main schema name string, so the application
** must ensure that the argument passed into this DBCONFIG option is unchanged
** until after the database connection closes.
**
**
+** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]]
** - SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
** - Usually, when a database in wal mode is closed or detached from a
** database handle, SQLite checks if this will mean that there are now no
** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to
@@ -2109,11 +2115,11 @@
** The second parameter is a pointer to an integer
** into which is written 0 or 1 to indicate whether checkpoints-on-close
** have been disabled - 0 if they are not disabled, 1 if they are.
**
**
-** - SQLITE_DBCONFIG_ENABLE_QPSG
+** [[SQLITE_DBCONFIG_ENABLE_QPSG]] - SQLITE_DBCONFIG_ENABLE_QPSG
** - ^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
** a single SQL query statement will always use the same algorithm regardless
** of values of [bound parameters].)^ The QPSG disables some query optimizations
** that look at the values of bound parameters, which can make some queries
@@ -2125,11 +2131,11 @@
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
** following this call.
**
**
-** - SQLITE_DBCONFIG_TRIGGER_EQP
+** [[SQLITE_DBCONFIG_TRIGGER_EQP]] - SQLITE_DBCONFIG_TRIGGER_EQP
** - By default, the output of EXPLAIN QUERY PLAN commands does not
** include output for any operations performed by trigger programs. This
** option is used to set or clear (the default) a flag that governs this
** behavior. The first parameter passed to this operation is an integer -
** positive to enable output for trigger programs, or zero to disable it,
@@ -2137,11 +2143,11 @@
** The second parameter is a pointer to an integer into which is written
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
** it is not disabled, 1 if it is.
**
**
-** - SQLITE_DBCONFIG_RESET_DATABASE
+** [[SQLITE_DBCONFIG_RESET_DATABASE]] - SQLITE_DBCONFIG_RESET_DATABASE
** - Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
** [VACUUM] in order to reset a database back to an empty database
** with no schema and no content. The following process works even for
** a badly corrupted database file:
**
@@ -2156,10 +2162,22 @@
** - sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
**
** Because resetting a database is destructive and irreversible, the
** process requires the use of this obscure API and multiple steps to help
** ensure that it does not happen by accident.
+**
+** [[SQLITE_DBCONFIG_DEFENSIVE]] - SQLITE_DBCONFIG_DEFENSIVE
+** - The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
+** "defensive" flag for a database connection. When the defensive
+** flag is enabled, language features that allow ordinary SQL to
+** deliberately corrupt the database file are disabled. The disabled
+** features include but are not limited to the following:
+**
+** - The [PRAGMA writable_schema=ON] statement.
+**
- Writes to the [sqlite_dbpage] virtual table.
+**
- Direct writes to [shadow tables].
+**
**
**
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
@@ -2169,11 +2187,12 @@
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
-#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
** METHOD: sqlite3
**
@@ -3607,13 +3626,23 @@
** be used just once or at most a few times and then destroyed using
** [sqlite3_finalize()] relatively soon. The current implementation acts
** on this hint by avoiding the use of [lookaside memory] so as not to
** deplete the limited store of lookaside memory. Future versions of
** SQLite may act on this hint differently.
+**
+** [[SQLITE_PREPARE_NORMALIZE]] ^(- SQLITE_PREPARE_NORMALIZE
+** - The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
+** representation of the SQL statement should be calculated and then
+** associated with the prepared statement, which can be obtained via
+** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
+** normalize a SQL statement are unspecified and subject to change.
+** At a minimum, literal values will be replaced with suitable
+** placeholders.
**
*/
#define SQLITE_PREPARE_PERSISTENT 0x01
+#define SQLITE_PREPARE_NORMALIZE 0x02
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
@@ -3767,10 +3796,15 @@
** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()],
** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()].
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
** string containing the SQL text of prepared statement P with
** [bound parameters] expanded.
+** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8
+** string containing the normalized SQL text of prepared statement P. The
+** semantics used to normalize a SQL statement are unspecified and subject
+** to change. At a minimum, literal values will be replaced with suitable
+** placeholders.
**
** ^(For example, if a prepared statement is created using the SQL
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
** and parameter :xyz is unbound, then sqlite3_sql() will return
** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
@@ -3782,18 +3816,20 @@
**
** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
** option causes sqlite3_expanded_sql() to always return NULL.
**
-** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
-** automatically freed when the prepared statement is finalized.
+** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P)
+** are managed by SQLite and are automatically freed when the prepared
+** statement is finalized.
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
** is obtained from [sqlite3_malloc()] and must be free by the application
** by passing it to [sqlite3_free()].
*/
SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
** METHOD: sqlite3_stmt
**
@@ -6279,10 +6315,13 @@
/* The methods above are in version 1 of the sqlite_module object. Those
** below are for version 2 and greater. */
int (*xSavepoint)(sqlite3_vtab *pVTab, int);
int (*xRelease)(sqlite3_vtab *pVTab, int);
int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
+ /* The methods above are in versions 1 and 2 of the sqlite_module object.
+ ** Those below are for version 3 and greater. */
+ int (*xShadowName)(const char*);
};
/*
** CAPI3REF: Virtual Table Indexing Information
** KEYWORDS: sqlite3_index_info
@@ -7201,10 +7240,11 @@
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
@@ -8613,10 +8653,11 @@
** These macros define the various options to the
** [sqlite3_vtab_config()] interface that [virtual table] implementations
** can use to customize and optimize their behavior.
**
**
+** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
** - SQLITE_VTAB_CONSTRAINT_SUPPORT
**
- Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
** where X is an integer. If X is zero, then the [virtual table] whose
** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not
@@ -9382,11 +9423,11 @@
int iLevel; /* Level of current node or entry */
int mxLevel; /* The largest iLevel value in the tree */
sqlite3_int64 iRowid; /* Rowid for current entry */
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
int eParentWithin; /* Visibility of parent node */
- int eWithin; /* OUT: Visiblity */
+ int eWithin; /* OUT: Visibility */
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
/* The following fields are only available in 3.8.11 and later */
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
};
@@ -9878,16 +9919,42 @@
** an application iterates through a changeset using an iterator created by
** this function, all changes that relate to a single table are visited
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
** another change for table X.
+**
+** The behavior of sqlite3changeset_start_v2() and its streaming equivalent
+** may be modified by passing a combination of
+** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter.
+**
+** Note that the sqlite3changeset_start_v2() API is still experimental
+** and therefore subject to change.
*/
SQLITE_API int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset /* Pointer to blob containing changeset */
);
+SQLITE_API int sqlite3changeset_start_v2(
+ sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
+ int nChangeset, /* Size of changeset blob in bytes */
+ void *pChangeset, /* Pointer to blob containing changeset */
+ int flags /* SESSION_CHANGESETSTART_* flags */
+);
+
+/*
+** CAPI3REF: Flags for sqlite3changeset_start_v2
+**
+** The following flags may passed via the 4th parameter to
+** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
+**
+**
- SQLITE_CHANGESETAPPLY_INVERT
-
+** Invert the changeset while iterating through it. This is equivalent to
+** inverting a changeset using sqlite3changeset_invert() before applying it.
+** It is an error to specify this flag with a patchset.
+*/
+#define SQLITE_CHANGESETSTART_INVERT 0x0002
/*
** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
@@ -10538,11 +10605,11 @@
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
- int flags /* Combination of SESSION_APPLY_* flags */
+ int flags /* SESSION_CHANGESETAPPLY_* flags */
);
/*
** CAPI3REF: Flags for sqlite3changeset_apply_v2
**
@@ -10556,12 +10623,18 @@
** SAVEPOINT is committed if the changeset or patchset is successfully
** applied, or rolled back if an error occurs. Specifying this flag
** causes the sessions module to omit this savepoint. In this case, if the
** caller has an open transaction or savepoint when apply_v2() is called,
** it may revert the partially applied changeset by rolling it back.
+**
+**
- SQLITE_CHANGESETAPPLY_INVERT
-
+** Invert the changeset before applying it. This is equivalent to inverting
+** a changeset using sqlite3changeset_invert() before applying it. It is
+** an error to specify this flag with a patchset.
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
+#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
/*
** CAPI3REF: Constants Passed To The Conflict Handler
**
** Values that may be passed as the second argument to a conflict-handler.
@@ -10950,10 +11023,16 @@
);
SQLITE_API int sqlite3changeset_start_strm(
sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
+);
+SQLITE_API int sqlite3changeset_start_v2_strm(
+ sqlite3_changeset_iter **pp,
+ int (*xInput)(void *pIn, void *pData, int *pnData),
+ void *pIn,
+ int flags
);
SQLITE_API int sqlite3session_changeset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
@@ -10977,10 +11056,49 @@
void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
+/*
+** CAPI3REF: Configure global parameters
+**
+** The sqlite3session_config() interface is used to make global configuration
+** changes to the sessions module in order to tune it to the specific needs
+** of the application.
+**
+** The sqlite3session_config() interface is not threadsafe. If it is invoked
+** while any other thread is inside any other sessions method then the
+** results are undefined. Furthermore, if it is invoked after any sessions
+** related objects have been created, the results are also undefined.
+**
+** The first argument to the sqlite3session_config() function must be one
+** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The
+** interpretation of the (void*) value passed as the second parameter and
+** the effect of calling this function depends on the value of the first
+** parameter.
+**
+**
+** - SQLITE_SESSION_CONFIG_STRMSIZE
-
+** By default, the sessions module streaming interfaces attempt to input
+** and output data in approximately 1 KiB chunks. This operand may be used
+** to set and query the value of this configuration setting. The pointer
+** passed as the second argument must point to a value of type (int).
+** If this value is greater than 0, it is used as the new streaming data
+** chunk size for both input and output. Before returning, the (int) value
+** pointed to by pArg is set to the final value of the streaming interface
+** chunk size.
+**
+**
+** This function returns SQLITE_OK if successful, or an SQLite error code
+** otherwise.
+*/
+SQLITE_API int sqlite3session_config(int op, void *pArg);
+
+/*
+** CAPI3REF: Values for sqlite3session_config().
+*/
+#define SQLITE_SESSION_CONFIG_STRMSIZE 1
/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus