diff options
Diffstat (limited to 'utils/benchmark/inputs/sqlite-btree.c.ppout')
-rw-r--r-- | utils/benchmark/inputs/sqlite-btree.c.ppout | 11397 |
1 files changed, 11397 insertions, 0 deletions
diff --git a/utils/benchmark/inputs/sqlite-btree.c.ppout b/utils/benchmark/inputs/sqlite-btree.c.ppout new file mode 100644 index 0000000..e73a0fa --- /dev/null +++ b/utils/benchmark/inputs/sqlite-btree.c.ppout @@ -0,0 +1,11397 @@ +# 1 "src/btree.c" +# 1 "<built-in>" +# 1 "<command-line>" +# 1 "src/btree.c" +# 16 "src/btree.c" +# 1 "src/btreeInt.h" 1 +# 216 "src/btreeInt.h" +# 1 "src/sqliteInt.h" 1 +# 59 "src/sqliteInt.h" +# 1 "src/msvc.h" 1 +# 60 "src/sqliteInt.h" 2 + + + + +# 1 "src/vxworks.h" 1 +# 65 "src/sqliteInt.h" 2 +# 167 "src/sqliteInt.h" +# 1 "./sqlite3.h" 1 +# 35 "./sqlite3.h" +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdarg.h" 1 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_defines.h" 1 +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdarg.h" 2 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_typedefs.h" 1 + + + +typedef int size_t; +typedef int __builtin_va_list; +typedef int __gnuc_va_list; +typedef int va_list; +typedef int __int8_t; +typedef int __uint8_t; +typedef int __int16_t; +typedef int __uint16_t; +typedef int __int_least16_t; +typedef int __uint_least16_t; +typedef int __int32_t; +typedef int __uint32_t; +typedef int __int64_t; +typedef int __uint64_t; +typedef int __int_least32_t; +typedef int __uint_least32_t; +typedef int __s8; +typedef int __u8; +typedef int __s16; +typedef int __u16; +typedef int __s32; +typedef int __u32; +typedef int __s64; +typedef int __u64; +typedef int _LOCK_T; +typedef int _LOCK_RECURSIVE_T; +typedef int _off_t; +typedef int __dev_t; +typedef int __uid_t; +typedef int __gid_t; +typedef int _off64_t; +typedef int _fpos_t; +typedef int _ssize_t; +typedef int wint_t; +typedef int _mbstate_t; +typedef int _flock_t; +typedef int _iconv_t; +typedef int __ULong; +typedef int __FILE; +typedef int ptrdiff_t; +typedef int wchar_t; +typedef int __off_t; +typedef int __pid_t; +typedef int __loff_t; +typedef int u_char; +typedef int u_short; +typedef int u_int; +typedef int u_long; +typedef int ushort; +typedef int uint; +typedef int clock_t; +typedef int time_t; +typedef int daddr_t; +typedef int caddr_t; +typedef int ino_t; +typedef int off_t; +typedef int dev_t; +typedef int uid_t; +typedef int gid_t; +typedef int pid_t; +typedef int key_t; +typedef int ssize_t; +typedef int mode_t; +typedef int nlink_t; +typedef int fd_mask; +typedef int _types_fd_set; +typedef int clockid_t; +typedef int timer_t; +typedef int useconds_t; +typedef int suseconds_t; +typedef int FILE; +typedef int fpos_t; +typedef int cookie_read_function_t; +typedef int cookie_write_function_t; +typedef int cookie_seek_function_t; +typedef int cookie_close_function_t; +typedef int cookie_io_functions_t; +typedef int div_t; +typedef int ldiv_t; +typedef int lldiv_t; +typedef int sigset_t; +typedef int __sigset_t; +typedef int _sig_func_ptr; +typedef int sig_atomic_t; +typedef int __tzrule_type; +typedef int __tzinfo_type; +typedef int mbstate_t; +typedef int sem_t; +typedef int pthread_t; +typedef int pthread_attr_t; +typedef int pthread_mutex_t; +typedef int pthread_mutexattr_t; +typedef int pthread_cond_t; +typedef int pthread_condattr_t; +typedef int pthread_key_t; +typedef int pthread_once_t; +typedef int pthread_rwlock_t; +typedef int pthread_rwlockattr_t; +typedef int pthread_spinlock_t; +typedef int pthread_barrier_t; +typedef int pthread_barrierattr_t; +typedef int jmp_buf; +typedef int rlim_t; +typedef int sa_family_t; +typedef int sigjmp_buf; +typedef int stack_t; +typedef int siginfo_t; +typedef int z_stream; + + +typedef int int8_t; +typedef int uint8_t; +typedef int int16_t; +typedef int uint16_t; +typedef int int32_t; +typedef int uint32_t; +typedef int int64_t; +typedef int uint64_t; + + +typedef int int_least8_t; +typedef int uint_least8_t; +typedef int int_least16_t; +typedef int uint_least16_t; +typedef int int_least32_t; +typedef int uint_least32_t; +typedef int int_least64_t; +typedef int uint_least64_t; + + +typedef int int_fast8_t; +typedef int uint_fast8_t; +typedef int int_fast16_t; +typedef int uint_fast16_t; +typedef int int_fast32_t; +typedef int uint_fast32_t; +typedef int int_fast64_t; +typedef int uint_fast64_t; + + +typedef int intptr_t; +typedef int uintptr_t; + + +typedef int intmax_t; +typedef int uintmax_t; + + +typedef _Bool bool; + + +typedef void* MirEGLNativeWindowType; +typedef void* MirEGLNativeDisplayType; +typedef struct MirConnection MirConnection; +typedef struct MirSurface MirSurface; +typedef struct MirSurfaceSpec MirSurfaceSpec; +typedef struct MirScreencast MirScreencast; +typedef struct MirPromptSession MirPromptSession; +typedef struct MirBufferStream MirBufferStream; +typedef struct MirPersistentId MirPersistentId; +typedef struct MirBlob MirBlob; +typedef struct MirDisplayConfig MirDisplayConfig; + + +typedef struct xcb_connection_t xcb_connection_t; +typedef uint32_t xcb_window_t; +typedef uint32_t xcb_visualid_t; +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdarg.h" 2 +# 36 "./sqlite3.h" 2 +# 162 "./sqlite3.h" + extern const char sqlite3_version[]; + const char *sqlite3_libversion(void); + const char *sqlite3_sourceid(void); + int sqlite3_libversion_number(void); +# 190 "./sqlite3.h" + int sqlite3_compileoption_used(const char *zOptName); + const char *sqlite3_compileoption_get(int N); +# 233 "./sqlite3.h" + int sqlite3_threadsafe(void); +# 249 "./sqlite3.h" +typedef struct sqlite3 sqlite3; +# 278 "./sqlite3.h" + typedef long long int sqlite_int64; + typedef unsigned long long int sqlite_uint64; + +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; +# 334 "./sqlite3.h" + int sqlite3_close(sqlite3*); + int sqlite3_close_v2(sqlite3*); + + + + + + +typedef int (*sqlite3_callback)(void*,int,char**, char**); +# 406 "./sqlite3.h" + int sqlite3_exec( + sqlite3*, + const char *sql, + int (*callback)(void*,int,char**,char**), + void *, + char **errmsg +); +# 677 "./sqlite3.h" +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; +}; +# 776 "./sqlite3.h" +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { + int iVersion; + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); + + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); + + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); + + +}; +# 1164 "./sqlite3.h" +typedef struct sqlite3_mutex sqlite3_mutex; +# 1174 "./sqlite3.h" +typedef struct sqlite3_api_routines sqlite3_api_routines; +# 1345 "./sqlite3.h" +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { + int iVersion; + int szOsFile; + int mxPathname; + sqlite3_vfs *pNext; + const char *zName; + void *pAppData; + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, + int flags, int *pOutFlags); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); + + + + + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); + + + + + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); + + + + + +}; +# 1523 "./sqlite3.h" + int sqlite3_initialize(void); + int sqlite3_shutdown(void); + int sqlite3_os_init(void); + int sqlite3_os_end(void); +# 1559 "./sqlite3.h" + int sqlite3_config(int, ...); +# 1578 "./sqlite3.h" + int sqlite3_db_config(sqlite3*, int op, ...); +# 1643 "./sqlite3.h" +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { + void *(*xMalloc)(int); + void (*xFree)(void*); + void *(*xRealloc)(void*,int); + int (*xSize)(void*); + int (*xRoundup)(int); + int (*xInit)(void*); + void (*xShutdown)(void*); + void *pAppData; +}; +# 2278 "./sqlite3.h" + int sqlite3_extended_result_codes(sqlite3*, int onoff); +# 2340 "./sqlite3.h" + sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +# 2350 "./sqlite3.h" + void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); +# 2408 "./sqlite3.h" + int sqlite3_changes(sqlite3*); +# 2445 "./sqlite3.h" + int sqlite3_total_changes(sqlite3*); +# 2482 "./sqlite3.h" + void sqlite3_interrupt(sqlite3*); +# 2517 "./sqlite3.h" + int sqlite3_complete(const char *sql); + int sqlite3_complete16(const void *sql); +# 2579 "./sqlite3.h" + int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); +# 2602 "./sqlite3.h" + int sqlite3_busy_timeout(sqlite3*, int ms); +# 2677 "./sqlite3.h" + int sqlite3_get_table( + sqlite3 *db, + const char *zSql, + char ***pazResult, + int *pnRow, + int *pnColumn, + char **pzErrmsg +); + void sqlite3_free_table(char **result); +# 2727 "./sqlite3.h" + char *sqlite3_mprintf(const char*,...); + char *sqlite3_vmprintf(const char*, va_list); + char *sqlite3_snprintf(int,char*,const char*, ...); + char *sqlite3_vsnprintf(int,char*,const char*, va_list); +# 2820 "./sqlite3.h" + void *sqlite3_malloc(int); + void *sqlite3_malloc64(sqlite3_uint64); + void *sqlite3_realloc(void*, int); + void *sqlite3_realloc64(void*, sqlite3_uint64); + void sqlite3_free(void*); + sqlite3_uint64 sqlite3_msize(void*); +# 2850 "./sqlite3.h" + sqlite3_int64 sqlite3_memory_used(void); + sqlite3_int64 sqlite3_memory_highwater(int resetFlag); +# 2874 "./sqlite3.h" + void sqlite3_randomness(int N, void *P); +# 2965 "./sqlite3.h" + int sqlite3_set_authorizer( + sqlite3*, + int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), + void *pUserData +); +# 3073 "./sqlite3.h" + void *sqlite3_trace(sqlite3*, + void(*xTrace)(void*,const char*), void*); + void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); +# 3164 "./sqlite3.h" + int sqlite3_trace_v2( + sqlite3*, + unsigned uMask, + int(*xCallback)(unsigned,void*,void*,void*), + void *pCtx +); +# 3203 "./sqlite3.h" + void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); +# 3432 "./sqlite3.h" + int sqlite3_open( + const char *filename, + sqlite3 **ppDb +); + int sqlite3_open16( + const void *filename, + sqlite3 **ppDb +); + int sqlite3_open_v2( + const char *filename, + sqlite3 **ppDb, + int flags, + const char *zVfs +); +# 3488 "./sqlite3.h" + const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); + int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); + sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +# 3545 "./sqlite3.h" + int sqlite3_errcode(sqlite3 *db); + int sqlite3_extended_errcode(sqlite3 *db); + const char *sqlite3_errmsg(sqlite3*); + const void *sqlite3_errmsg16(sqlite3*); + const char *sqlite3_errstr(int); +# 3575 "./sqlite3.h" +typedef struct sqlite3_stmt sqlite3_stmt; +# 3617 "./sqlite3.h" + int sqlite3_limit(sqlite3*, int id, int newVal); +# 3827 "./sqlite3.h" + int sqlite3_prepare( + sqlite3 *db, + const char *zSql, + int nByte, + sqlite3_stmt **ppStmt, + const char **pzTail +); + int sqlite3_prepare_v2( + sqlite3 *db, + const char *zSql, + int nByte, + sqlite3_stmt **ppStmt, + const char **pzTail +); + int sqlite3_prepare_v3( + sqlite3 *db, + const char *zSql, + int nByte, + unsigned int prepFlags, + sqlite3_stmt **ppStmt, + const char **pzTail +); + int sqlite3_prepare16( + sqlite3 *db, + const void *zSql, + int nByte, + sqlite3_stmt **ppStmt, + const void **pzTail +); + int sqlite3_prepare16_v2( + sqlite3 *db, + const void *zSql, + int nByte, + sqlite3_stmt **ppStmt, + const void **pzTail +); + int sqlite3_prepare16_v3( + sqlite3 *db, + const void *zSql, + int nByte, + unsigned int prepFlags, + sqlite3_stmt **ppStmt, + const void **pzTail +); +# 3910 "./sqlite3.h" + const char *sqlite3_sql(sqlite3_stmt *pStmt); + char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); + const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); +# 3948 "./sqlite3.h" + int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); +# 3960 "./sqlite3.h" + int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); +# 3981 "./sqlite3.h" + int sqlite3_stmt_busy(sqlite3_stmt*); +# 4023 "./sqlite3.h" +typedef struct sqlite3_value sqlite3_value; +# 4037 "./sqlite3.h" +typedef struct sqlite3_context sqlite3_context; +# 4157 "./sqlite3.h" + int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); + int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, + void(*)(void*)); + int sqlite3_bind_double(sqlite3_stmt*, int, double); + int sqlite3_bind_int(sqlite3_stmt*, int, int); + int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); + int sqlite3_bind_null(sqlite3_stmt*, int); + int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); + int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); + int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, + void(*)(void*), unsigned char encoding); + int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); + int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*)); + int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); + int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); +# 4192 "./sqlite3.h" + int sqlite3_bind_parameter_count(sqlite3_stmt*); +# 4220 "./sqlite3.h" + const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); +# 4238 "./sqlite3.h" + int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); +# 4248 "./sqlite3.h" + int sqlite3_clear_bindings(sqlite3_stmt*); +# 4264 "./sqlite3.h" + int sqlite3_column_count(sqlite3_stmt *pStmt); +# 4293 "./sqlite3.h" + const char *sqlite3_column_name(sqlite3_stmt*, int N); + const void *sqlite3_column_name16(sqlite3_stmt*, int N); +# 4342 "./sqlite3.h" + const char *sqlite3_column_database_name(sqlite3_stmt*,int); + const void *sqlite3_column_database_name16(sqlite3_stmt*,int); + const char *sqlite3_column_table_name(sqlite3_stmt*,int); + const void *sqlite3_column_table_name16(sqlite3_stmt*,int); + const char *sqlite3_column_origin_name(sqlite3_stmt*,int); + const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); +# 4379 "./sqlite3.h" + const char *sqlite3_column_decltype(sqlite3_stmt*,int); + const void *sqlite3_column_decltype16(sqlite3_stmt*,int); +# 4464 "./sqlite3.h" + int sqlite3_step(sqlite3_stmt*); +# 4485 "./sqlite3.h" + int sqlite3_data_count(sqlite3_stmt *pStmt); +# 4728 "./sqlite3.h" + const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); + double sqlite3_column_double(sqlite3_stmt*, int iCol); + int sqlite3_column_int(sqlite3_stmt*, int iCol); + sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); + const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); + const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); + sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); + int sqlite3_column_bytes(sqlite3_stmt*, int iCol); + int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); + int sqlite3_column_type(sqlite3_stmt*, int iCol); +# 4765 "./sqlite3.h" + int sqlite3_finalize(sqlite3_stmt *pStmt); +# 4792 "./sqlite3.h" + int sqlite3_reset(sqlite3_stmt *pStmt); +# 4904 "./sqlite3.h" + int sqlite3_create_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + int sqlite3_create_function16( + sqlite3 *db, + const void *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) +); + int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void(*xDestroy)(void*) +); + int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +); +# 4982 "./sqlite3.h" + int sqlite3_aggregate_count(sqlite3_context*); + int sqlite3_expired(sqlite3_stmt*); + int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); + int sqlite3_global_recover(void); + void sqlite3_thread_cleanup(void); + int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + void*,sqlite3_int64); +# 5119 "./sqlite3.h" + const void *sqlite3_value_blob(sqlite3_value*); + double sqlite3_value_double(sqlite3_value*); + int sqlite3_value_int(sqlite3_value*); + sqlite3_int64 sqlite3_value_int64(sqlite3_value*); + void *sqlite3_value_pointer(sqlite3_value*, const char*); + const unsigned char *sqlite3_value_text(sqlite3_value*); + const void *sqlite3_value_text16(sqlite3_value*); + const void *sqlite3_value_text16le(sqlite3_value*); + const void *sqlite3_value_text16be(sqlite3_value*); + int sqlite3_value_bytes(sqlite3_value*); + int sqlite3_value_bytes16(sqlite3_value*); + int sqlite3_value_type(sqlite3_value*); + int sqlite3_value_numeric_type(sqlite3_value*); + int sqlite3_value_nochange(sqlite3_value*); + int sqlite3_value_frombind(sqlite3_value*); +# 5145 "./sqlite3.h" + unsigned int sqlite3_value_subtype(sqlite3_value*); +# 5161 "./sqlite3.h" + sqlite3_value *sqlite3_value_dup(const sqlite3_value*); + void sqlite3_value_free(sqlite3_value*); +# 5207 "./sqlite3.h" + void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); +# 5222 "./sqlite3.h" + void *sqlite3_user_data(sqlite3_context*); +# 5234 "./sqlite3.h" + sqlite3 *sqlite3_context_db_handle(sqlite3_context*); +# 5293 "./sqlite3.h" + void *sqlite3_get_auxdata(sqlite3_context*, int N); + void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +# 5311 "./sqlite3.h" +typedef void (*sqlite3_destructor_type)(void*); +# 5441 "./sqlite3.h" + void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); + void sqlite3_result_blob64(sqlite3_context*,const void*, + sqlite3_uint64,void(*)(void*)); + void sqlite3_result_double(sqlite3_context*, double); + void sqlite3_result_error(sqlite3_context*, const char*, int); + void sqlite3_result_error16(sqlite3_context*, const void*, int); + void sqlite3_result_error_toobig(sqlite3_context*); + void sqlite3_result_error_nomem(sqlite3_context*); + void sqlite3_result_error_code(sqlite3_context*, int); + void sqlite3_result_int(sqlite3_context*, int); + void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); + void sqlite3_result_null(sqlite3_context*); + void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); + void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, + void(*)(void*), unsigned char encoding); + void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); + void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); + void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); + void sqlite3_result_value(sqlite3_context*, sqlite3_value*); + void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*)); + void sqlite3_result_zeroblob(sqlite3_context*, int n); + int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); +# 5477 "./sqlite3.h" + void sqlite3_result_subtype(sqlite3_context*,unsigned int); +# 5559 "./sqlite3.h" + int sqlite3_create_collation( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); + int sqlite3_create_collation_v2( + sqlite3*, + const char *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*), + void(*xDestroy)(void*) +); + int sqlite3_create_collation16( + sqlite3*, + const void *zName, + int eTextRep, + void *pArg, + int(*xCompare)(void*,int,const void*,int,const void*) +); +# 5609 "./sqlite3.h" + int sqlite3_collation_needed( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const char*) +); + int sqlite3_collation_needed16( + sqlite3*, + void*, + void(*)(void*,sqlite3*,int eTextRep,const void*) +); +# 5692 "./sqlite3.h" + int sqlite3_sleep(int); +# 5750 "./sqlite3.h" + extern char *sqlite3_temp_directory; +# 5787 "./sqlite3.h" + extern char *sqlite3_data_directory; +# 5808 "./sqlite3.h" + int sqlite3_win32_set_directory( + unsigned long type, + void *zValue +); + int sqlite3_win32_set_directory8(unsigned long type, const char *zValue); + int sqlite3_win32_set_directory16(unsigned long type, const void *zValue); +# 5846 "./sqlite3.h" + int sqlite3_get_autocommit(sqlite3*); +# 5859 "./sqlite3.h" + sqlite3 *sqlite3_db_handle(sqlite3_stmt*); +# 5876 "./sqlite3.h" + const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); +# 5886 "./sqlite3.h" + int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +# 5902 "./sqlite3.h" + sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); +# 5951 "./sqlite3.h" + void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); + void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +# 6003 "./sqlite3.h" + void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), + void* +); +# 6044 "./sqlite3.h" + int sqlite3_enable_shared_cache(int); +# 6060 "./sqlite3.h" + int sqlite3_release_memory(int); +# 6074 "./sqlite3.h" + int sqlite3_db_release_memory(sqlite3*); +# 6127 "./sqlite3.h" + sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); +# 6138 "./sqlite3.h" + void sqlite3_soft_heap_limit(int N); +# 6210 "./sqlite3.h" + int sqlite3_table_column_metadata( + sqlite3 *db, + const char *zDbName, + const char *zTableName, + const char *zColumnName, + char const **pzDataType, + char const **pzCollSeq, + int *pNotNull, + int *pPrimaryKey, + int *pAutoinc +); +# 6266 "./sqlite3.h" + int sqlite3_load_extension( + sqlite3 *db, + const char *zFile, + const char *zProc, + char **pzErrMsg +); +# 6298 "./sqlite3.h" + int sqlite3_enable_load_extension(sqlite3 *db, int onoff); +# 6336 "./sqlite3.h" + int sqlite3_auto_extension(void(*xEntryPoint)(void)); +# 6348 "./sqlite3.h" + int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); + + + + + + + + void sqlite3_reset_auto_extension(void); +# 6370 "./sqlite3.h" +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; +# 6391 "./sqlite3.h" +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + + + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); + + + int (*xShadowName)(const char*); +}; +# 6525 "./sqlite3.h" +struct sqlite3_index_info { + + int nConstraint; + struct sqlite3_index_constraint { + int iColumn; + unsigned char op; + unsigned char usable; + int iTermOffset; + } *aConstraint; + int nOrderBy; + struct sqlite3_index_orderby { + int iColumn; + unsigned char desc; + } *aOrderBy; + + struct sqlite3_index_constraint_usage { + int argvIndex; + unsigned char omit; + } *aConstraintUsage; + int idxNum; + char *idxStr; + int needToFreeIdxStr; + int orderByConsumed; + double estimatedCost; + + sqlite3_int64 estimatedRows; + + int idxFlags; + + sqlite3_uint64 colUsed; +}; +# 6616 "./sqlite3.h" + int sqlite3_create_module( + sqlite3 *db, + const char *zName, + const sqlite3_module *p, + void *pClientData +); + int sqlite3_create_module_v2( + sqlite3 *db, + const char *zName, + const sqlite3_module *p, + void *pClientData, + void(*xDestroy)(void*) +); +# 6648 "./sqlite3.h" +struct sqlite3_vtab { + const sqlite3_module *pModule; + int nRef; + char *zErrMsg; + +}; +# 6672 "./sqlite3.h" +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; + +}; +# 6685 "./sqlite3.h" + int sqlite3_declare_vtab(sqlite3*, const char *zSQL); +# 6704 "./sqlite3.h" + int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); +# 6728 "./sqlite3.h" +typedef struct sqlite3_blob sqlite3_blob; +# 6813 "./sqlite3.h" + int sqlite3_blob_open( + sqlite3*, + const char *zDb, + const char *zTable, + const char *zColumn, + sqlite3_int64 iRow, + int flags, + sqlite3_blob **ppBlob +); +# 6846 "./sqlite3.h" + int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); +# 6869 "./sqlite3.h" + int sqlite3_blob_close(sqlite3_blob *); +# 6885 "./sqlite3.h" + int sqlite3_blob_bytes(sqlite3_blob *); +# 6914 "./sqlite3.h" + int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); +# 6956 "./sqlite3.h" + int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); +# 6987 "./sqlite3.h" + sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); + int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); + int sqlite3_vfs_unregister(sqlite3_vfs*); +# 7105 "./sqlite3.h" + sqlite3_mutex *sqlite3_mutex_alloc(int); + void sqlite3_mutex_free(sqlite3_mutex*); + void sqlite3_mutex_enter(sqlite3_mutex*); + int sqlite3_mutex_try(sqlite3_mutex*); + void sqlite3_mutex_leave(sqlite3_mutex*); +# 7176 "./sqlite3.h" +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { + int (*xMutexInit)(void); + int (*xMutexEnd)(void); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); +}; +# 7219 "./sqlite3.h" + int sqlite3_mutex_held(sqlite3_mutex*); + int sqlite3_mutex_notheld(sqlite3_mutex*); +# 7260 "./sqlite3.h" + sqlite3_mutex *sqlite3_db_mutex(sqlite3*); +# 7303 "./sqlite3.h" + int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); +# 7322 "./sqlite3.h" + int sqlite3_test_control(int op, ...); +# 7410 "./sqlite3.h" + int sqlite3_keyword_count(void); + int sqlite3_keyword_name(int,const char**,int*); + int sqlite3_keyword_check(const char*,int); +# 7430 "./sqlite3.h" +typedef struct sqlite3_str sqlite3_str; +# 7457 "./sqlite3.h" + sqlite3_str *sqlite3_str_new(sqlite3*); +# 7472 "./sqlite3.h" + char *sqlite3_str_finish(sqlite3_str*); +# 7506 "./sqlite3.h" + void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); + void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); + void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); + void sqlite3_str_appendall(sqlite3_str*, const char *zIn); + void sqlite3_str_appendchar(sqlite3_str*, int N, char C); + void sqlite3_str_reset(sqlite3_str*); +# 7542 "./sqlite3.h" + int sqlite3_str_errcode(sqlite3_str*); + int sqlite3_str_length(sqlite3_str*); + char *sqlite3_str_value(sqlite3_str*); +# 7572 "./sqlite3.h" + int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); + int sqlite3_status64( + int op, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, + int resetFlag +); +# 7682 "./sqlite3.h" + int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +# 7835 "./sqlite3.h" + int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); +# 7911 "./sqlite3.h" +typedef struct sqlite3_pcache sqlite3_pcache; +# 7923 "./sqlite3.h" +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { + void *pBuf; + void *pExtra; +}; +# 8088 "./sqlite3.h" +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { + int iVersion; + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); +}; + + + + + + +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { + void *pArg; + int (*xInit)(void*); + void (*xShutdown)(void*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); +}; +# 8137 "./sqlite3.h" +typedef struct sqlite3_backup sqlite3_backup; +# 8325 "./sqlite3.h" + sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, + const char *zDestName, + sqlite3 *pSource, + const char *zSourceName +); + int sqlite3_backup_step(sqlite3_backup *p, int nPage); + int sqlite3_backup_finish(sqlite3_backup *p); + int sqlite3_backup_remaining(sqlite3_backup *p); + int sqlite3_backup_pagecount(sqlite3_backup *p); +# 8451 "./sqlite3.h" + int sqlite3_unlock_notify( + sqlite3 *pBlocked, + void (*xNotify)(void **apArg, int nArg), + void *pNotifyArg +); +# 8466 "./sqlite3.h" + int sqlite3_stricmp(const char *, const char *); + int sqlite3_strnicmp(const char *, const char *, int); +# 8484 "./sqlite3.h" + int sqlite3_strglob(const char *zGlob, const char *zStr); +# 8507 "./sqlite3.h" + int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); +# 8530 "./sqlite3.h" + void sqlite3_log(int iErrCode, const char *zFormat, ...); +# 8566 "./sqlite3.h" + void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), + void* +); +# 8601 "./sqlite3.h" + int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); +# 8623 "./sqlite3.h" + int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); +# 8717 "./sqlite3.h" + int sqlite3_wal_checkpoint_v2( + sqlite3 *db, + const char *zDb, + int eMode, + int *pnLog, + int *pnCkpt +); +# 8753 "./sqlite3.h" + int sqlite3_vtab_config(sqlite3*, int op, ...); +# 8807 "./sqlite3.h" + int sqlite3_vtab_on_conflict(sqlite3 *); +# 8826 "./sqlite3.h" + int sqlite3_vtab_nochange(sqlite3_context*); +# 8841 "./sqlite3.h" + const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +# 8946 "./sqlite3.h" + int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, + int idx, + int iScanStatusOp, + void *pOut +); +# 8962 "./sqlite3.h" + void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); +# 8994 "./sqlite3.h" + int sqlite3_db_cacheflush(sqlite3*); +# 9108 "./sqlite3.h" + int sqlite3_system_errno(sqlite3*); +# 9130 "./sqlite3.h" +typedef struct sqlite3_snapshot { + unsigned char hidden[48]; +} sqlite3_snapshot; +# 9177 "./sqlite3.h" + int sqlite3_snapshot_get( + sqlite3 *db, + const char *zSchema, + sqlite3_snapshot **ppSnapshot +); +# 9226 "./sqlite3.h" + int sqlite3_snapshot_open( + sqlite3 *db, + const char *zSchema, + sqlite3_snapshot *pSnapshot +); +# 9243 "./sqlite3.h" + void sqlite3_snapshot_free(sqlite3_snapshot*); +# 9270 "./sqlite3.h" + int sqlite3_snapshot_cmp( + sqlite3_snapshot *p1, + sqlite3_snapshot *p2 +); +# 9298 "./sqlite3.h" + int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); +# 9336 "./sqlite3.h" + unsigned char *sqlite3_serialize( + sqlite3 *db, + const char *zSchema, + sqlite3_int64 *piSize, + unsigned int mFlags +); +# 9388 "./sqlite3.h" + int sqlite3_deserialize( + sqlite3 *db, + const char *zSchema, + unsigned char *pData, + sqlite3_int64 szDb, + sqlite3_int64 szBuf, + unsigned mFlags +); +# 9457 "./sqlite3.h" +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; + + + + + + + + typedef double sqlite3_rtree_dbl; +# 9475 "./sqlite3.h" + int sqlite3_rtree_geometry_callback( + sqlite3 *db, + const char *zGeom, + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), + void *pContext +); + + + + + + +struct sqlite3_rtree_geometry { + void *pContext; + int nParam; + sqlite3_rtree_dbl *aParam; + void *pUser; + void (*xDelUser)(void *); +}; + + + + + + + + int sqlite3_rtree_query_callback( + sqlite3 *db, + const char *zQueryFunc, + int (*xQueryFunc)(sqlite3_rtree_query_info*), + void *pContext, + void (*xDestructor)(void*) +); +# 9519 "./sqlite3.h" +struct sqlite3_rtree_query_info { + void *pContext; + int nParam; + sqlite3_rtree_dbl *aParam; + void *pUser; + void (*xDelUser)(void*); + sqlite3_rtree_dbl *aCoord; + unsigned int *anQueue; + int nCoord; + int iLevel; + int mxLevel; + sqlite3_int64 iRowid; + sqlite3_rtree_dbl rParentScore; + int eParentWithin; + int eWithin; + sqlite3_rtree_dbl rScore; + + sqlite3_value **apSqlParam; +}; +# 11252 "./sqlite3.h" +typedef struct Fts5ExtensionApi Fts5ExtensionApi; +typedef struct Fts5Context Fts5Context; +typedef struct Fts5PhraseIter Fts5PhraseIter; + +typedef void (*fts5_extension_function)( + const Fts5ExtensionApi *pApi, + Fts5Context *pFts, + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +); + +struct Fts5PhraseIter { + const unsigned char *a; + const unsigned char *b; +}; +# 11480 "./sqlite3.h" +struct Fts5ExtensionApi { + int iVersion; + + void *(*xUserData)(Fts5Context*); + + int (*xColumnCount)(Fts5Context*); + int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); + int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); + + int (*xTokenize)(Fts5Context*, + const char *pText, int nText, + void *pCtx, + int (*xToken)(void*, int, const char*, int, int, int) + ); + + int (*xPhraseCount)(Fts5Context*); + int (*xPhraseSize)(Fts5Context*, int iPhrase); + + int (*xInstCount)(Fts5Context*, int *pnInst); + int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff); + + sqlite3_int64 (*xRowid)(Fts5Context*); + int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn); + int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken); + + int (*xQueryPhrase)(Fts5Context*, int iPhrase, void *pUserData, + int(*)(const Fts5ExtensionApi*,Fts5Context*,void*) + ); + int (*xSetAuxdata)(Fts5Context*, void *pAux, void(*xDelete)(void*)); + void *(*xGetAuxdata)(Fts5Context*, int bClear); + + int (*xPhraseFirst)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*, int*); + void (*xPhraseNext)(Fts5Context*, Fts5PhraseIter*, int *piCol, int *piOff); + + int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); + void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); +}; +# 11714 "./sqlite3.h" +typedef struct Fts5Tokenizer Fts5Tokenizer; +typedef struct fts5_tokenizer fts5_tokenizer; +struct fts5_tokenizer { + int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + void (*xDelete)(Fts5Tokenizer*); + int (*xTokenize)(Fts5Tokenizer*, + void *pCtx, + int flags, + const char *pText, int nText, + int (*xToken)( + void *pCtx, + int tflags, + const char *pToken, + int nToken, + int iStart, + int iEnd + ) + ); +}; +# 11751 "./sqlite3.h" +typedef struct fts5_api fts5_api; +struct fts5_api { + int iVersion; + + + int (*xCreateTokenizer)( + fts5_api *pApi, + const char *zName, + void *pContext, + fts5_tokenizer *pTokenizer, + void (*xDestroy)(void*) + ); + + + int (*xFindTokenizer)( + fts5_api *pApi, + const char *zName, + void **ppContext, + fts5_tokenizer *pTokenizer + ); + + + int (*xCreateFunction)( + fts5_api *pApi, + const char *zName, + void *pContext, + fts5_extension_function xFunction, + void (*xDestroy)(void*) + ); +}; +# 168 "src/sqliteInt.h" 2 +# 178 "src/sqliteInt.h" +# 1 "src/sqliteLimit.h" 1 +# 179 "src/sqliteInt.h" 2 +# 529 "src/sqliteInt.h" +# 1 "src/hash.h" 1 +# 19 "src/hash.h" +typedef struct Hash Hash; +typedef struct HashElem HashElem; +# 43 "src/hash.h" +struct Hash { + unsigned int htsize; + unsigned int count; + HashElem *first; + struct _ht { + unsigned int count; + HashElem *chain; + } *ht; +}; + + + + + + + +struct HashElem { + HashElem *next, *prev; + void *data; + const char *pKey; +}; + + + + +void sqlite3HashInit(Hash*); +void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); +void *sqlite3HashFind(const Hash*, const char *pKey); +void sqlite3HashClear(Hash*); +# 530 "src/sqliteInt.h" 2 +# 1 "./parse.h" 1 +# 531 "src/sqliteInt.h" 2 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdio.h" 1 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_defines.h" 1 +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdio.h" 2 +# 532 "src/sqliteInt.h" 2 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdlib.h" 1 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_defines.h" 1 +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdlib.h" 2 +# 533 "src/sqliteInt.h" 2 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/string.h" 1 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_defines.h" 1 +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/string.h" 2 +# 534 "src/sqliteInt.h" 2 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/assert.h" 1 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_defines.h" 1 +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/assert.h" 2 +# 535 "src/sqliteInt.h" 2 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stddef.h" 1 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_defines.h" 1 +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stddef.h" 2 +# 536 "src/sqliteInt.h" 2 +# 734 "src/sqliteInt.h" +typedef sqlite_int64 i64; +typedef sqlite_uint64 u64; +typedef unsigned int u32; +typedef unsigned short int u16; +typedef short int i16; +typedef unsigned char u8; +typedef signed char i8; +# 759 "src/sqliteInt.h" + typedef u32 tRowcnt; +# 785 "src/sqliteInt.h" +typedef short int LogEst; +# 809 "src/sqliteInt.h" + typedef u64 uptr; +# 971 "src/sqliteInt.h" +typedef struct BusyHandler BusyHandler; +struct BusyHandler { + int (*xBusyHandler)(void *,int); + void *pBusyArg; + int nBusy; + u8 bExtraFileArg; +}; +# 1066 "src/sqliteInt.h" +typedef struct AggInfo AggInfo; +typedef struct AuthContext AuthContext; +typedef struct AutoincInfo AutoincInfo; +typedef struct Bitvec Bitvec; +typedef struct CollSeq CollSeq; +typedef struct Column Column; +typedef struct Db Db; +typedef struct Schema Schema; +typedef struct Expr Expr; +typedef struct ExprList ExprList; +typedef struct FKey FKey; +typedef struct FuncDestructor FuncDestructor; +typedef struct FuncDef FuncDef; +typedef struct FuncDefHash FuncDefHash; +typedef struct IdList IdList; +typedef struct Index Index; +typedef struct IndexSample IndexSample; +typedef struct KeyClass KeyClass; +typedef struct KeyInfo KeyInfo; +typedef struct Lookaside Lookaside; +typedef struct LookasideSlot LookasideSlot; +typedef struct Module Module; +typedef struct NameContext NameContext; +typedef struct Parse Parse; +typedef struct PreUpdate PreUpdate; +typedef struct PrintfArguments PrintfArguments; +typedef struct RenameToken RenameToken; +typedef struct RowSet RowSet; +typedef struct Savepoint Savepoint; +typedef struct Select Select; +typedef struct SQLiteThread SQLiteThread; +typedef struct SelectDest SelectDest; +typedef struct SrcList SrcList; +typedef struct sqlite3_str StrAccum; +typedef struct Table Table; +typedef struct TableLock TableLock; +typedef struct Token Token; +typedef struct TreeView TreeView; +typedef struct Trigger Trigger; +typedef struct TriggerPrg TriggerPrg; +typedef struct TriggerStep TriggerStep; +typedef struct UnpackedRecord UnpackedRecord; +typedef struct Upsert Upsert; +typedef struct VTable VTable; +typedef struct VtabCtx VtabCtx; +typedef struct Walker Walker; +typedef struct WhereInfo WhereInfo; +typedef struct Window Window; +typedef struct With With; +# 1127 "src/sqliteInt.h" + typedef u64 Bitmask; +# 1148 "src/sqliteInt.h" +typedef int VList; + + + + + + +# 1 "src/btree.h" 1 +# 39 "src/btree.h" +typedef struct Btree Btree; +typedef struct BtCursor BtCursor; +typedef struct BtShared BtShared; +typedef struct BtreePayload BtreePayload; + + +int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, + const char *zFilename, + sqlite3 *db, + Btree **ppBtree, + int flags, + int vfsFlags +); +# 65 "src/btree.h" +int sqlite3BtreeClose(Btree*); +int sqlite3BtreeSetCacheSize(Btree*,int); +int sqlite3BtreeSetSpillSize(Btree*,int); + + int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); + +int sqlite3BtreeSetPagerFlags(Btree*,unsigned); +int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); +int sqlite3BtreeGetPageSize(Btree*); +int sqlite3BtreeMaxPageCount(Btree*,int); +u32 sqlite3BtreeLastPage(Btree*); +int sqlite3BtreeSecureDelete(Btree*,int); +int sqlite3BtreeGetOptimalReserve(Btree*); +int sqlite3BtreeGetReserveNoMutex(Btree *p); +int sqlite3BtreeSetAutoVacuum(Btree *, int); +int sqlite3BtreeGetAutoVacuum(Btree *); +int sqlite3BtreeBeginTrans(Btree*,int,int*); +int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); +int sqlite3BtreeCommitPhaseTwo(Btree*, int); +int sqlite3BtreeCommit(Btree*); +int sqlite3BtreeRollback(Btree*,int,int); +int sqlite3BtreeBeginStmt(Btree*,int); +int sqlite3BtreeCreateTable(Btree*, int*, int flags); +int sqlite3BtreeIsInTrans(Btree*); +int sqlite3BtreeIsInReadTrans(Btree*); +int sqlite3BtreeIsInBackup(Btree*); +void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); +int sqlite3BtreeSchemaLocked(Btree *pBtree); + +int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); + +int sqlite3BtreeSavepoint(Btree *, int, int); + +const char *sqlite3BtreeGetFilename(Btree *); +const char *sqlite3BtreeGetJournalname(Btree *); +int sqlite3BtreeCopyFile(Btree *, Btree *); + +int sqlite3BtreeIncrVacuum(Btree *); +# 117 "src/btree.h" +int sqlite3BtreeDropTable(Btree*, int, int*); +int sqlite3BtreeClearTable(Btree*, int, int*); +int sqlite3BtreeClearTableOfCursor(BtCursor*); +int sqlite3BtreeTripAllCursors(Btree*, int, int); + +void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); +int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); + +int sqlite3BtreeNewDb(Btree *p); +# 226 "src/btree.h" +int sqlite3BtreeCursor( + Btree*, + int iTable, + int wrFlag, + struct KeyInfo*, + BtCursor *pCursor +); +BtCursor *sqlite3BtreeFakeValidCursor(void); +int sqlite3BtreeCursorSize(void); +void sqlite3BtreeCursorZero(BtCursor*); +void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); + + + + +int sqlite3BtreeCloseCursor(BtCursor*); +int sqlite3BtreeMovetoUnpacked( + BtCursor*, + UnpackedRecord *pUnKey, + i64 intKey, + int bias, + int *pRes +); +int sqlite3BtreeCursorHasMoved(BtCursor*); +int sqlite3BtreeCursorRestore(BtCursor*, int*); +int sqlite3BtreeDelete(BtCursor*, u8 flags); +# 291 "src/btree.h" +struct BtreePayload { + const void *pKey; + sqlite3_int64 nKey; + const void *pData; + sqlite3_value *aMem; + u16 nMem; + int nData; + int nZero; +}; + +int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, + int flags, int seekResult); +int sqlite3BtreeFirst(BtCursor*, int *pRes); +int sqlite3BtreeLast(BtCursor*, int *pRes); +int sqlite3BtreeNext(BtCursor*, int flags); +int sqlite3BtreeEof(BtCursor*); +int sqlite3BtreePrevious(BtCursor*, int flags); +i64 sqlite3BtreeIntegerKey(BtCursor*); + + + +int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); +const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); +u32 sqlite3BtreePayloadSize(BtCursor*); +sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); + +char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); +struct Pager *sqlite3BtreePager(Btree*); +i64 sqlite3BtreeRowCountEst(BtCursor*); + + +int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); +int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); +void sqlite3BtreeIncrblobCursor(BtCursor *); + +void sqlite3BtreeClearCursor(BtCursor *); +int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); +int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); +int sqlite3BtreeIsReadonly(Btree *pBt); +int sqlite3HeaderSizeBtree(void); + + + + +int sqlite3BtreeCursorIsValidNN(BtCursor*); + + +int sqlite3BtreeCount(BtCursor *, i64 *); +# 347 "src/btree.h" + int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +# 356 "src/btree.h" + void sqlite3BtreeEnter(Btree*); + void sqlite3BtreeEnterAll(sqlite3*); + int sqlite3BtreeSharable(Btree*); + void sqlite3BtreeEnterCursor(BtCursor*); + int sqlite3BtreeConnectionCount(Btree*); +# 370 "src/btree.h" + void sqlite3BtreeLeave(Btree*); + void sqlite3BtreeLeaveCursor(BtCursor*); + void sqlite3BtreeLeaveAll(sqlite3*); +# 1156 "src/sqliteInt.h" 2 +# 1 "src/vdbe.h" 1 +# 20 "src/vdbe.h" +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdio.h" 1 +# 1 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/_fake_defines.h" 1 +# 2 "/usr/local/google/home/eliben/eli/pycparser/utils/fake_libc_include/stdio.h" 2 +# 21 "src/vdbe.h" 2 + + + + + + +typedef struct Vdbe Vdbe; + + + + + +typedef struct sqlite3_value Mem; +typedef struct SubProgram SubProgram; + + + + + + +struct VdbeOp { + u8 opcode; + signed char p4type; + u16 p5; + int p1; + int p2; + int p3; + union p4union { + int i; + void *p; + char *z; + i64 *pI64; + double *pReal; + FuncDef *pFunc; + sqlite3_context *pCtx; + CollSeq *pColl; + Mem *pMem; + VTable *pVtab; + KeyInfo *pKeyInfo; + int *ai; + SubProgram *pProgram; + Table *pTab; + + + + int (*xAdvance)(BtCursor *, int); + } p4; +# 79 "src/vdbe.h" +}; +typedef struct VdbeOp VdbeOp; + + + + + +struct SubProgram { + VdbeOp *aOp; + int nOp; + int nMem; + int nCsr; + u8 *aOnce; + void *token; + SubProgram *pNext; +}; + + + + + +struct VdbeOpList { + u8 opcode; + signed char p1; + signed char p2; + signed char p3; +}; +typedef struct VdbeOpList VdbeOpList; +# 169 "src/vdbe.h" +# 1 "./opcodes.h" 1 +# 170 "src/vdbe.h" 2 +# 181 "src/vdbe.h" +Vdbe *sqlite3VdbeCreate(Parse*); +int sqlite3VdbeAddOp0(Vdbe*,int); +int sqlite3VdbeAddOp1(Vdbe*,int,int); +int sqlite3VdbeAddOp2(Vdbe*,int,int,int); +int sqlite3VdbeGoto(Vdbe*,int); +int sqlite3VdbeLoadString(Vdbe*,int,const char*); +void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); +int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); +int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); +int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); +int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); +void sqlite3VdbeEndCoroutine(Vdbe*,int); +# 205 "src/vdbe.h" +VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); + + void sqlite3VdbeExplain(Parse*,u8,const char*,...); + void sqlite3VdbeExplainPop(Parse*); + int sqlite3VdbeExplainParent(Parse*); +# 224 "src/vdbe.h" +void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8); +void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1); +void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2); +void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3); +void sqlite3VdbeChangeP5(Vdbe*, u16 P5); +void sqlite3VdbeJumpHere(Vdbe*, int addr); +int sqlite3VdbeChangeToNoop(Vdbe*, int addr); +int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); +void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); +void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); +void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); +void sqlite3VdbeUsesBtree(Vdbe*, int); +VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); +int sqlite3VdbeMakeLabel(Parse*); +void sqlite3VdbeRunOnlyOnce(Vdbe*); +void sqlite3VdbeReusable(Vdbe*); +void sqlite3VdbeDelete(Vdbe*); +void sqlite3VdbeClearObject(sqlite3*,Vdbe*); +void sqlite3VdbeMakeReady(Vdbe*,Parse*); +int sqlite3VdbeFinalize(Vdbe*); +void sqlite3VdbeResolveLabel(Vdbe*, int); +int sqlite3VdbeCurrentAddr(Vdbe*); + + + +void sqlite3VdbeResetStepResult(Vdbe*); +void sqlite3VdbeRewind(Vdbe*); +int sqlite3VdbeReset(Vdbe*); +void sqlite3VdbeSetNumCols(Vdbe*,int); +int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); +void sqlite3VdbeCountChanges(Vdbe*); +sqlite3 *sqlite3VdbeDb(Vdbe*); +u8 sqlite3VdbePrepareFlags(Vdbe*); +void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8); + + + + +void sqlite3VdbeSwap(Vdbe*,Vdbe*); +VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); +sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); +void sqlite3VdbeSetVarmask(Vdbe*, int); + + char *sqlite3VdbeExpandSql(Vdbe*, const char*); + +int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); +int sqlite3BlobCompare(const Mem*, const Mem*); + +void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); +int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); +UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); + +typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); +RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); + + +void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); + + +int sqlite3NotPureFunc(sqlite3_context*); +# 1157 "src/sqliteInt.h" 2 +# 1 "src/pager.h" 1 +# 33 "src/pager.h" +typedef u32 Pgno; + + + + +typedef struct Pager Pager; + + + + +typedef struct PgHdr DbPage; +# 116 "src/pager.h" +int sqlite3PagerOpen( + sqlite3_vfs*, + Pager **ppPager, + const char*, + int, + int, + int, + void(*)(DbPage*) +); +int sqlite3PagerClose(Pager *pPager, sqlite3*); +int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); + + +void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); +int sqlite3PagerSetPagesize(Pager*, u32*, int); + + + +int sqlite3PagerMaxPageCount(Pager*, int); +void sqlite3PagerSetCachesize(Pager*, int); +int sqlite3PagerSetSpillsize(Pager*, int); +void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); +void sqlite3PagerShrink(Pager*); +void sqlite3PagerSetFlags(Pager*,unsigned); +int sqlite3PagerLockingMode(Pager *, int); +int sqlite3PagerSetJournalMode(Pager *, int); +int sqlite3PagerGetJournalMode(Pager*); +int sqlite3PagerOkToChangeJournalMode(Pager*); +i64 sqlite3PagerJournalSizeLimit(Pager *, i64); +sqlite3_backup **sqlite3PagerBackupPtr(Pager*); +int sqlite3PagerFlush(Pager*); + + +int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); +DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); +void sqlite3PagerRef(DbPage*); +void sqlite3PagerUnref(DbPage*); +void sqlite3PagerUnrefNotNull(DbPage*); +void sqlite3PagerUnrefPageOne(DbPage*); + + +int sqlite3PagerWrite(DbPage*); +void sqlite3PagerDontWrite(DbPage*); +int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); +int sqlite3PagerPageRefcount(DbPage*); +void *sqlite3PagerGetData(DbPage *); +void *sqlite3PagerGetExtra(DbPage *); + + +void sqlite3PagerPagecount(Pager*, int*); +int sqlite3PagerBegin(Pager*, int exFlag, int); +int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); +int sqlite3PagerExclusiveLock(Pager*); +int sqlite3PagerSync(Pager *pPager, const char *zMaster); +int sqlite3PagerCommitPhaseTwo(Pager*); +int sqlite3PagerRollback(Pager*); +int sqlite3PagerOpenSavepoint(Pager *pPager, int n); +int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); +int sqlite3PagerSharedLock(Pager *pPager); + + + int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*); + int sqlite3PagerWalSupported(Pager *pPager); + int sqlite3PagerWalCallback(Pager *pPager); + int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); + int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); +# 200 "src/pager.h" +u8 sqlite3PagerIsreadonly(Pager*); +u32 sqlite3PagerDataVersion(Pager*); + + + +int sqlite3PagerMemUsed(Pager*); +const char *sqlite3PagerFilename(Pager*, int); +sqlite3_vfs *sqlite3PagerVfs(Pager*); +sqlite3_file *sqlite3PagerFile(Pager*); +sqlite3_file *sqlite3PagerJrnlFile(Pager*); +const char *sqlite3PagerJournalname(Pager*); +void *sqlite3PagerTempSpace(Pager*); +int sqlite3PagerIsMemdb(Pager*); +void sqlite3PagerCacheStat(Pager *, int, int, int *); +void sqlite3PagerClearCache(Pager*); +int sqlite3SectorSize(sqlite3_file *); + + + + + + + +void sqlite3PagerTruncateImage(Pager*,Pgno); + +void sqlite3PagerRekey(DbPage*, Pgno, u16); +# 1158 "src/sqliteInt.h" 2 +# 1 "src/pcache.h" 1 +# 18 "src/pcache.h" +typedef struct PgHdr PgHdr; +typedef struct PCache PCache; + + + + + +struct PgHdr { + sqlite3_pcache_page *pPage; + void *pData; + void *pExtra; + PCache *pCache; + PgHdr *pDirty; + Pager *pPager; + Pgno pgno; + + + + u16 flags; + + + + + + + i16 nRef; + PgHdr *pDirtyNext; + PgHdr *pDirtyPrev; + + +}; +# 62 "src/pcache.h" +int sqlite3PcacheInitialize(void); +void sqlite3PcacheShutdown(void); + + + + +void sqlite3PCacheBufferSetup(void *, int sz, int n); + + + + + +int sqlite3PcacheOpen( + int szPage, + int szExtra, + int bPurgeable, + int (*xStress)(void*, PgHdr*), + void *pStress, + PCache *pToInit +); + + +int sqlite3PcacheSetPageSize(PCache *, int); + + + + +int sqlite3PcacheSize(void); + + + + +sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); +int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); +PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); +void sqlite3PcacheRelease(PgHdr*); + +void sqlite3PcacheDrop(PgHdr*); +void sqlite3PcacheMakeDirty(PgHdr*); +void sqlite3PcacheMakeClean(PgHdr*); +void sqlite3PcacheCleanAll(PCache*); +void sqlite3PcacheClearWritable(PCache*); + + +void sqlite3PcacheMove(PgHdr*, Pgno); + + +void sqlite3PcacheTruncate(PCache*, Pgno x); + + +PgHdr *sqlite3PcacheDirtyList(PCache*); + + +void sqlite3PcacheClose(PCache*); + + +void sqlite3PcacheClearSyncFlags(PCache *); + + +void sqlite3PcacheClear(PCache*); + + +int sqlite3PcacheRefCount(PCache*); + + +void sqlite3PcacheRef(PgHdr*); + +int sqlite3PcachePageRefcount(PgHdr*); + + +int sqlite3PcachePagecount(PCache*); +# 153 "src/pcache.h" +void sqlite3PcacheSetCachesize(PCache *, int); +# 163 "src/pcache.h" +int sqlite3PcacheSetSpillsize(PCache *, int); + + +void sqlite3PcacheShrink(PCache*); +# 177 "src/pcache.h" +void sqlite3PCacheSetDefault(void); + + +int sqlite3HeaderSizePcache(void); +int sqlite3HeaderSizePcache1(void); + + +int sqlite3PCachePercentDirty(PCache*); +# 1159 "src/sqliteInt.h" 2 +# 1 "src/os.h" 1 +# 27 "src/os.h" +# 1 "src/os_setup.h" 1 +# 28 "src/os.h" 2 +# 158 "src/os.h" +int sqlite3OsInit(void); + + + + +void sqlite3OsClose(sqlite3_file*); +int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +int sqlite3OsTruncate(sqlite3_file*, i64 size); +int sqlite3OsSync(sqlite3_file*, int); +int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +int sqlite3OsLock(sqlite3_file*, int); +int sqlite3OsUnlock(sqlite3_file*, int); +int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +int sqlite3OsFileControl(sqlite3_file*,int,void*); +void sqlite3OsFileControlHint(sqlite3_file*,int,void*); + +int sqlite3OsSectorSize(sqlite3_file *id); +int sqlite3OsDeviceCharacteristics(sqlite3_file *id); + +int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +void sqlite3OsShmBarrier(sqlite3_file *id); +int sqlite3OsShmUnmap(sqlite3_file *id, int); + +int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); +int sqlite3OsUnfetch(sqlite3_file *, i64, void *); + + + + + +int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); + +void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +void sqlite3OsDlError(sqlite3_vfs *, int, char *); +void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +void sqlite3OsDlClose(sqlite3_vfs *, void *); + +int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +int sqlite3OsSleep(sqlite3_vfs *, int); +int sqlite3OsGetLastError(sqlite3_vfs*); +int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); + + + + + +int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +void sqlite3OsCloseFree(sqlite3_file *); +# 1160 "src/sqliteInt.h" 2 +# 1 "src/mutex.h" 1 +# 1161 "src/sqliteInt.h" 2 +# 1200 "src/sqliteInt.h" +struct Db { + char *zDbSName; + Btree *pBt; + u8 safety_level; + u8 bSyncSet; + Schema *pSchema; +}; +# 1225 "src/sqliteInt.h" +struct Schema { + int schema_cookie; + int iGeneration; + Hash tblHash; + Hash idxHash; + Hash trigHash; + Hash fkeyHash; + Table *pSeqTab; + u8 file_format; + u8 enc; + u16 schemaFlags; + int cache_size; +}; +# 1289 "src/sqliteInt.h" +struct Lookaside { + u32 bDisable; + u16 sz; + u8 bMalloced; + u32 nSlot; + u32 anStat[3]; + LookasideSlot *pInit; + LookasideSlot *pFree; + void *pStart; + void *pEnd; +}; +struct LookasideSlot { + LookasideSlot *pNext; +}; +# 1313 "src/sqliteInt.h" +struct FuncDefHash { + FuncDef *a[23]; +}; +# 1352 "src/sqliteInt.h" + typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, + const char*); +# 1372 "src/sqliteInt.h" +struct sqlite3 { + sqlite3_vfs *pVfs; + struct Vdbe *pVdbe; + CollSeq *pDfltColl; + sqlite3_mutex *mutex; + Db *aDb; + int nDb; + u32 mDbFlags; + u64 flags; + i64 lastRowid; + i64 szMmap; + u32 nSchemaLock; + unsigned int openFlags; + int errCode; + int errMask; + int iSysErrno; + u16 dbOptFlags; + u8 enc; + u8 autoCommit; + u8 temp_store; + u8 mallocFailed; + u8 bBenignMalloc; + u8 dfltLockMode; + signed char nextAutovac; + u8 suppressErr; + u8 vtabOnConflict; + u8 isTransactionSavepoint; + u8 mTrace; + u8 noSharedCache; + u8 nSqlExec; + int nextPagesize; + u32 magic; + int nChange; + int nTotalChange; + int aLimit[(11 +1)]; + int nMaxSorterMmap; + struct sqlite3InitInfo { + int newTnum; + u8 iDb; + u8 busy; + unsigned orphanTrigger : 1; + unsigned imposterTable : 1; + unsigned reopenMemdb : 1; + } init; + int nVdbeActive; + int nVdbeRead; + int nVdbeWrite; + int nVdbeExec; + int nVDestroy; + int nExtension; + void **aExtension; + int (*xTrace)(u32,void*,void*,void*); + void *pTraceArg; + + void (*xProfile)(void*,const char*,u64); + void *pProfileArg; + + void *pCommitArg; + int (*xCommitCallback)(void*); + void *pRollbackArg; + void (*xRollbackCallback)(void*); + void *pUpdateArg; + void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); + Parse *pParse; +# 1444 "src/sqliteInt.h" + int (*xWalCallback)(void *, sqlite3 *, const char *, int); + void *pWalArg; + + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); + void *pCollNeededArg; + sqlite3_value *pErr; + union { + volatile int isInterrupted; + double notUsed1; + } u1; + Lookaside lookaside; + + sqlite3_xauth xAuth; + void *pAuthArg; + + + int (*xProgress)(void *); + void *pProgressArg; + unsigned nProgressOps; + + + int nVTrans; + Hash aModule; + VtabCtx *pVtabCtx; + VTable **aVTrans; + VTable *pDisconnect; + + Hash aFunc; + Hash aCollSeq; + BusyHandler busyHandler; + Db aDbStatic[2]; + Savepoint *pSavepoint; + int busyTimeout; + int nSavepoint; + int nStatement; + i64 nDeferredCons; + i64 nDeferredImmCons; + int *pnBytesFreed; +# 1503 "src/sqliteInt.h" +}; +# 1632 "src/sqliteInt.h" +struct FuncDef { + i8 nArg; + u32 funcFlags; + void *pUserData; + FuncDef *pNext; + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); + void (*xFinalize)(sqlite3_context*); + void (*xValue)(sqlite3_context*); + void (*xInverse)(sqlite3_context*,int,sqlite3_value**); + const char *zName; + union { + FuncDef *pHash; + FuncDestructor *pDestructor; + } u; +}; +# 1662 "src/sqliteInt.h" +struct FuncDestructor { + int nRef; + void (*xDestroy)(void *); + void *pUserData; +}; +# 1788 "src/sqliteInt.h" +struct Savepoint { + char *zName; + i64 nDeferredCons; + i64 nDeferredImmCons; + Savepoint *pNext; +}; +# 1809 "src/sqliteInt.h" +struct Module { + const sqlite3_module *pModule; + const char *zName; + void *pAux; + void (*xDestroy)(void *); + Table *pEpoTab; +}; + + + + + +struct Column { + char *zName; + Expr *pDflt; + char *zColl; + u8 notNull; + char affinity; + u8 szEst; + u8 colFlags; +}; +# 1848 "src/sqliteInt.h" +struct CollSeq { + char *zName; + u8 enc; + void *pUser; + int (*xCmp)(void*,int, const void*, int, const void*); + void (*xDel)(void*); +}; +# 1948 "src/sqliteInt.h" +struct VTable { + sqlite3 *db; + Module *pMod; + sqlite3_vtab *pVtab; + int nRef; + u8 bConstraint; + int iSavepoint; + VTable *pNext; +}; + + + + + +struct Table { + char *zName; + Column *aCol; + Index *pIndex; + Select *pSelect; + FKey *pFKey; + char *zColAff; + ExprList *pCheck; + + int tnum; + u32 nTabRef; + u32 tabFlags; + i16 iPKey; + i16 nCol; + LogEst nRowLogEst; + LogEst szTabRow; + + + + u8 keyConf; + + int addColOffset; + + + int nModuleArg; + char **azModuleArg; + VTable *pVTable; + + Trigger *pTrigger; + Schema *pSchema; + Table *pNextZombie; +}; +# 2078 "src/sqliteInt.h" +struct FKey { + Table *pFrom; + FKey *pNextFrom; + char *zTo; + FKey *pNextTo; + FKey *pPrevTo; + int nCol; + + u8 isDeferred; + u8 aAction[2]; + Trigger *apTrigger[2]; + struct sColMap { + int iFrom; + char *zCol; + } aCol[1]; +}; +# 2143 "src/sqliteInt.h" +struct KeyInfo { + u32 nRef; + u8 enc; + u16 nKeyField; + u16 nAllField; + sqlite3 *db; + u8 *aSortOrder; + CollSeq *aColl[1]; +}; +# 2188 "src/sqliteInt.h" +struct UnpackedRecord { + KeyInfo *pKeyInfo; + Mem *aMem; + u16 nField; + i8 default_rc; + u8 errCode; + i8 r1; + i8 r2; + u8 eqSeen; +}; +# 2234 "src/sqliteInt.h" +struct Index { + char *zName; + i16 *aiColumn; + LogEst *aiRowLogEst; + Table *pTable; + char *zColAff; + Index *pNext; + Schema *pSchema; + u8 *aSortOrder; + const char **azColl; + Expr *pPartIdxWhere; + ExprList *aColExpr; + int tnum; + LogEst szIdxRow; + u16 nKeyCol; + u16 nColumn; + u8 onError; + unsigned idxType:2; + unsigned bUnordered:1; + unsigned uniqNotNull:1; + unsigned isResized:1; + unsigned isCovering:1; + unsigned noSkipScan:1; + unsigned hasStat1:1; + unsigned bNoQuery:1; + unsigned bAscKeyBug:1; +# 2268 "src/sqliteInt.h" + Bitmask colNotIdxed; +}; +# 2296 "src/sqliteInt.h" +struct IndexSample { + void *p; + int n; + tRowcnt *anEq; + tRowcnt *anLt; + tRowcnt *anDLt; +}; +# 2320 "src/sqliteInt.h" +struct Token { + const char *z; + unsigned int n; +}; +# 2338 "src/sqliteInt.h" +struct AggInfo { + u8 directMode; + + u8 useSortingIdx; + + int sortingIdx; + int sortingIdxPTab; + int nSortingColumn; + int mnReg, mxReg; + ExprList *pGroupBy; + struct AggInfo_col { + Table *pTab; + int iTable; + int iColumn; + int iSorterColumn; + int iMem; + Expr *pExpr; + } *aCol; + int nColumn; + int nAccumulator; + + + struct AggInfo_func { + Expr *pExpr; + FuncDef *pFunc; + int iMem; + int iDistinct; + } *aFunc; + int nFunc; +}; +# 2380 "src/sqliteInt.h" +typedef i16 ynVar; +# 2448 "src/sqliteInt.h" +struct Expr { + u8 op; + char affinity; + u32 flags; + union { + char *zToken; + int iValue; + } u; + + + + + + + Expr *pLeft; + Expr *pRight; + union { + ExprList *pList; + Select *pSelect; + } x; + + + + + + + + int nHeight; + + int iTable; + + + + + ynVar iColumn; + + + i16 iAgg; + i16 iRightJoinTable; + u8 op2; + + + AggInfo *pAggInfo; + union { + Table *pTab; + + Window *pWin; + struct { + int iAddr; + int regReturn; + } sub; + } y; +}; +# 2598 "src/sqliteInt.h" +struct ExprList { + int nExpr; + struct ExprList_item { + Expr *pExpr; + char *zName; + char *zSpan; + u8 sortOrder; + unsigned done :1; + unsigned bSpanIsTab :1; + unsigned reusable :1; + unsigned bSorterRef :1; + union { + struct { + u16 iOrderByCol; + u16 iAlias; + } x; + int iConstExprReg; + } u; + } a[1]; +}; +# 2634 "src/sqliteInt.h" +struct IdList { + struct IdList_item { + char *zName; + int idx; + } *a; + int nId; +}; +# 2661 "src/sqliteInt.h" +struct SrcList { + int nSrc; + u32 nAlloc; + struct SrcList_item { + Schema *pSchema; + char *zDatabase; + char *zName; + char *zAlias; + Table *pTab; + Select *pSelect; + int addrFillSub; + int regReturn; + int regResult; + struct { + u8 jointype; + unsigned notIndexed :1; + unsigned isIndexedBy :1; + unsigned isTabFunc :1; + unsigned isCorrelated :1; + unsigned viaCoroutine :1; + unsigned isRecursive :1; + } fg; + int iCursor; + Expr *pOn; + IdList *pUsing; + Bitmask colUsed; + union { + char *zIndexedBy; + ExprList *pFuncArg; + } u1; + Index *pIBIndex; + } a[1]; +}; +# 2761 "src/sqliteInt.h" +struct NameContext { + Parse *pParse; + SrcList *pSrcList; + union { + ExprList *pEList; + AggInfo *pAggInfo; + Upsert *pUpsert; + } uNC; + NameContext *pNext; + int nRef; + int nErr; + int ncFlags; + Select *pWinSelect; +}; +# 2815 "src/sqliteInt.h" +struct Upsert { + ExprList *pUpsertTarget; + Expr *pUpsertTargetWhere; + ExprList *pUpsertSet; + Expr *pUpsertWhere; + + + + + Index *pUpsertIdx; + SrcList *pUpsertSrc; + int regData; + int iDataCur; + int iIdxCur; +}; +# 2848 "src/sqliteInt.h" +struct Select { + ExprList *pEList; + u8 op; + LogEst nSelectRow; + u32 selFlags; + int iLimit, iOffset; + u32 selId; + int addrOpenEphm[2]; + SrcList *pSrc; + Expr *pWhere; + ExprList *pGroupBy; + Expr *pHaving; + ExprList *pOrderBy; + Select *pPrior; + Select *pNext; + Expr *pLimit; + With *pWith; + + Window *pWin; + Window *pWinDefn; + +}; +# 2987 "src/sqliteInt.h" +struct SelectDest { + u8 eDest; + int iSDParm; + int iSdst; + int nSdst; + char *zAffSdst; + ExprList *pOrderBy; +}; +# 3005 "src/sqliteInt.h" +struct AutoincInfo { + AutoincInfo *pNext; + Table *pTab; + int iDb; + int regCtr; +}; +# 3030 "src/sqliteInt.h" +struct TriggerPrg { + Trigger *pTrigger; + TriggerPrg *pNext; + SubProgram *pProgram; + int orconf; + u32 aColmask[2]; +}; +# 3049 "src/sqliteInt.h" + typedef unsigned int yDbMask; +# 3073 "src/sqliteInt.h" +struct Parse { + sqlite3 *db; + char *zErrMsg; + Vdbe *pVdbe; + int rc; + u8 colNamesSet; + u8 checkSchema; + u8 nested; + u8 nTempReg; + u8 isMultiWrite; + u8 mayAbort; + u8 hasCompound; + u8 okConstFactor; + u8 disableLookaside; + u8 disableVtab; + int nRangeReg; + int iRangeReg; + int nErr; + int nTab; + int nMem; + int szOpAlloc; + int iSelfTab; + + int nLabel; + int nLabelAlloc; + int *aLabel; + ExprList *pConstExpr; + Token constraintName; + yDbMask writeMask; + yDbMask cookieMask; + int regRowid; + int regRoot; + int nMaxArg; + int nSelect; + + int nTableLock; + TableLock *aTableLock; + + AutoincInfo *pAinc; + Parse *pToplevel; + Table *pTriggerTab; + Parse *pParentParse; + int addrCrTab; + u32 nQueryLoop; + u32 oldmask; + u32 newmask; + u8 eTriggerOp; + u8 eOrconf; + u8 disableTriggers; +# 3130 "src/sqliteInt.h" + int aTempReg[8]; + Token sNameToken; +# 3140 "src/sqliteInt.h" + Token sLastToken; + ynVar nVar; + u8 iPkSortOrder; + u8 explain; + + u8 eParseMode; + + + int nVtabLock; + + int nHeight; + + int addrExplain; + + VList *pVList; + Vdbe *pReprepare; + const char *zTail; + Table *pNewTable; + Index *pNewIndex; + + + Trigger *pNewTrigger; + const char *zAuthContext; + + Token sArg; + Table **apVtabLock; + + Table *pZombieTab; + TriggerPrg *pTriggerPrg; + With *pWith; + With *pWithToFree; + + RenameToken *pRename; + +}; +# 3214 "src/sqliteInt.h" +struct AuthContext { + const char *zAuthContext; + Parse *pParse; +}; +# 3266 "src/sqliteInt.h" +struct Trigger { + char *zName; + char *table; + u8 op; + u8 tr_tm; + Expr *pWhen; + IdList *pColumns; + + Schema *pSchema; + Schema *pTabSchema; + TriggerStep *step_list; + Trigger *pNext; +}; +# 3328 "src/sqliteInt.h" +struct TriggerStep { + u8 op; + u8 orconf; + Trigger *pTrig; + Select *pSelect; + char *zTarget; + Expr *pWhere; + ExprList *pExprList; + IdList *pIdList; + Upsert *pUpsert; + char *zSpan; + TriggerStep *pNext; + TriggerStep *pLast; +}; + + + + + + +typedef struct DbFixer DbFixer; +struct DbFixer { + Parse *pParse; + Schema *pSchema; + int bVarOnly; + const char *zDb; + const char *zType; + const Token *pName; +}; + + + + + +struct sqlite3_str { + sqlite3 *db; + char *zText; + u32 nAlloc; + u32 mxAlloc; + u32 nChar; + u8 accError; + u8 printfFlags; +}; +# 3382 "src/sqliteInt.h" +typedef struct { + sqlite3 *db; + char **pzErrMsg; + int iDb; + int rc; + u32 mInitFlags; + u32 nInitRow; +} InitData; +# 3401 "src/sqliteInt.h" +struct Sqlite3Config { + int bMemstat; + int bCoreMutex; + int bFullMutex; + int bOpenUri; + int bUseCis; + int bSmallMalloc; + int mxStrlen; + int neverCorrupt; + int szLookaside; + int nLookaside; + int nStmtSpill; + sqlite3_mem_methods m; + sqlite3_mutex_methods mutex; + sqlite3_pcache_methods2 pcache2; + void *pHeap; + int nHeap; + int mnReq, mxReq; + sqlite3_int64 szMmap; + sqlite3_int64 mxMmap; + void *pPage; + int szPage; + int nPage; + int mxParserStack; + int sharedCacheEnabled; + u32 szPma; + + + int isInit; + int inProgress; + int isMutexInit; + int isMallocInit; + int isPCacheInit; + int nRefInitMutex; + sqlite3_mutex *pInitMutex; + void (*xLog)(void*,int,const char*); + void *pLogArg; +# 3453 "src/sqliteInt.h" + int (*xTestCallback)(int); + + int bLocaltimeFault; + int bInternalFunctions; + int iOnceResetThreshold; + u32 szSorterRef; +}; +# 3482 "src/sqliteInt.h" +struct Walker { + Parse *pParse; + int (*xExprCallback)(Walker*, Expr*); + int (*xSelectCallback)(Walker*,Select*); + void (*xSelectCallback2)(Walker*,Select*); + int walkerDepth; + u8 eCode; + union { + NameContext *pNC; + int n; + int iCur; + SrcList *pSrcList; + struct SrcCount *pSrcCount; + struct CCurHint *pCCurHint; + int *aiCol; + struct IdxCover *pIdxCover; + struct IdxExprTrans *pIdxTrans; + ExprList *pGroupBy; + Select *pSelect; + struct WindowRewrite *pRewrite; + struct WhereConst *pConst; + struct RenameCtx *pRename; + } u; +}; + + +int sqlite3WalkExpr(Walker*, Expr*); +int sqlite3WalkExprList(Walker*, ExprList*); +int sqlite3WalkSelect(Walker*, Select*); +int sqlite3WalkSelectExpr(Walker*, Select*); +int sqlite3WalkSelectFrom(Walker*, Select*); +int sqlite3ExprWalkNoop(Walker*, Expr*); +int sqlite3SelectWalkNoop(Walker*, Select*); +int sqlite3SelectWalkFail(Walker*, Select*); +# 3532 "src/sqliteInt.h" +struct With { + int nCte; + With *pOuter; + struct Cte { + char *zName; + ExprList *pCols; + Select *pSelect; + const char *zCteErr; + } a[1]; +}; +# 3572 "src/sqliteInt.h" +struct Window { + char *zName; + char *zBase; + ExprList *pPartition; + ExprList *pOrderBy; + u8 eFrmType; + u8 eStart; + u8 eEnd; + u8 bImplicitFrame; + u8 eExclude; + Expr *pStart; + Expr *pEnd; + Window *pNextWin; + Expr *pFilter; + FuncDef *pFunc; + int iEphCsr; + int regAccum; + int regResult; + int csrApp; + int regApp; + int regPart; + Expr *pOwner; + int nBufferCol; + int iArgCol; + int regOne; + int regStartRowid; + int regEndRowid; +}; + + +void sqlite3WindowDelete(sqlite3*, Window*); +void sqlite3WindowListDelete(sqlite3 *db, Window *p); +Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); +void sqlite3WindowAttach(Parse*, Expr*, Window*); +int sqlite3WindowCompare(Parse*, Window*, Window*); +void sqlite3WindowCodeInit(Parse*, Window*); +void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); +int sqlite3WindowRewrite(Parse*, Select*); +int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); +void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); +Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); +Window *sqlite3WindowListDup(sqlite3 *db, Window *p); +void sqlite3WindowFunctions(void); +void sqlite3WindowChain(Parse*, Window*, Window*); +Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*); +# 3640 "src/sqliteInt.h" +int sqlite3ReportError(int iErr, int lineno, const char *zType); +int sqlite3CorruptError(int); +int sqlite3MisuseError(int); +int sqlite3CantopenError(int); +# 3710 "src/sqliteInt.h" +int sqlite3IsIdChar(u8); + + + + +int sqlite3StrICmp(const char*,const char*); +int sqlite3Strlen30(const char*); + +char *sqlite3ColumnType(Column*,char*); + + +int sqlite3MallocInit(void); +void sqlite3MallocEnd(void); +void *sqlite3Malloc(u64); +void *sqlite3MallocZero(u64); +void *sqlite3DbMallocZero(sqlite3*, u64); +void *sqlite3DbMallocRaw(sqlite3*, u64); +void *sqlite3DbMallocRawNN(sqlite3*, u64); +char *sqlite3DbStrDup(sqlite3*,const char*); +char *sqlite3DbStrNDup(sqlite3*,const char*, u64); +char *sqlite3DbSpanDup(sqlite3*,const char*,const char*); +void *sqlite3Realloc(void*, u64); +void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); +void *sqlite3DbRealloc(sqlite3 *, void *, u64); +void sqlite3DbFree(sqlite3*, void*); +void sqlite3DbFreeNN(sqlite3*, void*); +int sqlite3MallocSize(void*); +int sqlite3DbMallocSize(sqlite3*, void*); +void *sqlite3PageMalloc(int); +void sqlite3PageFree(void*); +void sqlite3MemSetDefault(void); + +void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); + +int sqlite3HeapNearlyFull(void); +# 3777 "src/sqliteInt.h" + sqlite3_mutex_methods const *sqlite3DefaultMutex(void); + sqlite3_mutex_methods const *sqlite3NoopMutex(void); + sqlite3_mutex *sqlite3MutexAlloc(int); + int sqlite3MutexInit(void); + int sqlite3MutexEnd(void); + + + void sqlite3MemoryBarrier(void); + + + + +sqlite3_int64 sqlite3StatusValue(int); +void sqlite3StatusUp(int, int); +void sqlite3StatusDown(int, int); +void sqlite3StatusHighwater(int, int); +int sqlite3LookasideUsed(sqlite3*,int*); + + +sqlite3_mutex *sqlite3Pcache1Mutex(void); +sqlite3_mutex *sqlite3MallocMutex(void); +# 3809 "src/sqliteInt.h" + int sqlite3IsNaN(double); +# 3819 "src/sqliteInt.h" +struct PrintfArguments { + int nArg; + int nUsed; + sqlite3_value **apArg; +}; + +char *sqlite3MPrintf(sqlite3*,const char*, ...); +char *sqlite3VMPrintf(sqlite3*,const char*, va_list); +# 3848 "src/sqliteInt.h" +void sqlite3SetString(char **, sqlite3*, const char*); +void sqlite3ErrorMsg(Parse*, const char*, ...); +int sqlite3ErrorToParser(sqlite3*,int); +void sqlite3Dequote(char*); +void sqlite3DequoteExpr(Expr*); +void sqlite3TokenInit(Token*,char*); +int sqlite3KeywordCode(const unsigned char*, int); +int sqlite3RunParser(Parse*, const char*, char **); +void sqlite3FinishCoding(Parse*); +int sqlite3GetTempReg(Parse*); +void sqlite3ReleaseTempReg(Parse*,int); +int sqlite3GetTempRange(Parse*,int); +void sqlite3ReleaseTempRange(Parse*,int,int); +void sqlite3ClearTempRegCache(Parse*); + + + +Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); +Expr *sqlite3Expr(sqlite3*,int,const char*); +void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); +Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); +void sqlite3PExprAddSelect(Parse*, Expr*, Select*); +Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); +Expr *sqlite3ExprSimplifiedAndOr(Expr*); +Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); +void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); +void sqlite3ExprDelete(sqlite3*, Expr*); +void sqlite3ExprUnmapAndDelete(Parse*, Expr*); +ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); +ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); +void sqlite3ExprListSetSortOrder(ExprList*,int); +void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); +void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); +void sqlite3ExprListDelete(sqlite3*, ExprList*); +u32 sqlite3ExprListFlags(const ExprList*); +int sqlite3IndexHasDuplicateRootPage(Index*); +int sqlite3Init(sqlite3*, char**); +int sqlite3InitCallback(void*, int, char**, char**); +int sqlite3InitOne(sqlite3*, int, char**, u32); +void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); + +Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); + +void sqlite3ResetAllSchemasOfConnection(sqlite3*); +void sqlite3ResetOneSchema(sqlite3*,int); +void sqlite3CollapseDatabaseArray(sqlite3*); +void sqlite3CommitInternalChanges(sqlite3*); +void sqlite3DeleteColumnNames(sqlite3*,Table*); +int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); +void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*); +Table *sqlite3ResultSetOfSelect(Parse*,Select*); +void sqlite3OpenMasterTable(Parse *, int); +Index *sqlite3PrimaryKeyIndex(Table*); +i16 sqlite3ColumnOfIndex(Index*, i16); +void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); + + + + + +void sqlite3AddColumn(Parse*,Token*,Token*); +void sqlite3AddNotNull(Parse*, int); +void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); +void sqlite3AddCheckConstraint(Parse*, Expr*); +void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); +void sqlite3AddCollateType(Parse*, Token*); +void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); +int sqlite3ParseUri(const char*,const char*,unsigned int*, + sqlite3_vfs**,char**,char **); + + + + + +Btree *sqlite3DbNameToBtree(sqlite3*,const char*); + + + + + int sqlite3FaultSim(int); + + +Bitvec *sqlite3BitvecCreate(u32); +int sqlite3BitvecTest(Bitvec*, u32); +int sqlite3BitvecTestNotNull(Bitvec*, u32); +int sqlite3BitvecSet(Bitvec*, u32); +void sqlite3BitvecClear(Bitvec*, u32, void*); +void sqlite3BitvecDestroy(Bitvec*); +u32 sqlite3BitvecSize(Bitvec*); + +int sqlite3BitvecBuiltinTest(int,int*); + + +RowSet *sqlite3RowSetInit(sqlite3*); +void sqlite3RowSetDelete(void*); +void sqlite3RowSetClear(void*); +void sqlite3RowSetInsert(RowSet*, i64); +int sqlite3RowSetTest(RowSet*, int iBatch, i64); +int sqlite3RowSetNext(RowSet*, i64*); + +void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); + + + int sqlite3ViewGetColumnNames(Parse*,Table*); + + + + + + + +void sqlite3DropTable(Parse*, SrcList*, int, int); +void sqlite3CodeDropTable(Parse*, Table*, int, int); +void sqlite3DeleteTable(sqlite3*, Table*); +void sqlite3FreeIndex(sqlite3*, Index*); + + void sqlite3AutoincrementBegin(Parse *pParse); + void sqlite3AutoincrementEnd(Parse *pParse); + + + + +void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); +void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); +IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); +int sqlite3IdListIndex(IdList*,const char*); +SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); +SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); +SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, + Token*, Select*, Expr*, IdList*); +void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); +void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); +int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); +void sqlite3SrcListShiftJoinType(SrcList*); +void sqlite3SrcListAssignCursors(Parse*, SrcList*); +void sqlite3IdListDelete(sqlite3*, IdList*); +void sqlite3SrcListDelete(sqlite3*, SrcList*); +Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); +void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, + Expr*, int, int, u8); +void sqlite3DropIndex(Parse*, SrcList*, int); +int sqlite3Select(Parse*, Select*, SelectDest*); +Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, + Expr*,ExprList*,u32,Expr*); +void sqlite3SelectDelete(sqlite3*, Select*); +Table *sqlite3SrcListLookup(Parse*, SrcList*); +int sqlite3IsReadOnly(Parse*, Table*, int); +void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); + + + +void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); +void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, + Upsert*); +WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); +void sqlite3WhereEnd(WhereInfo*); +LogEst sqlite3WhereOutputRowCount(WhereInfo*); +int sqlite3WhereIsDistinct(WhereInfo*); +int sqlite3WhereIsOrdered(WhereInfo*); +int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); +int sqlite3WhereIsSorted(WhereInfo*); +int sqlite3WhereContinueLabel(WhereInfo*); +int sqlite3WhereBreakLabel(WhereInfo*); +int sqlite3WhereOkOnePass(WhereInfo*, int*); + + + +void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); +int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); +void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); +void sqlite3ExprCodeMove(Parse*, int, int, int); +void sqlite3ExprCode(Parse*, Expr*, int); +void sqlite3ExprCodeCopy(Parse*, Expr*, int); +void sqlite3ExprCodeFactorable(Parse*, Expr*, int); +int sqlite3ExprCodeAtInit(Parse*, Expr*, int); +int sqlite3ExprCodeTemp(Parse*, Expr*, int*); +int sqlite3ExprCodeTarget(Parse*, Expr*, int); +void sqlite3ExprCodeAndCache(Parse*, Expr*, int); +int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); + + + + +void sqlite3ExprIfTrue(Parse*, Expr*, int, int); +void sqlite3ExprIfFalse(Parse*, Expr*, int, int); +void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int); +Table *sqlite3FindTable(sqlite3*,const char*, const char*); + + +Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); +Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); +Index *sqlite3FindIndex(sqlite3*,const char*, const char*); +void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); +void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); +void sqlite3Vacuum(Parse*,Token*,Expr*); +int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*); +char *sqlite3NameFromToken(sqlite3*, Token*); +int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); +int sqlite3ExprCompareSkip(Expr*, Expr*, int); +int sqlite3ExprListCompare(ExprList*, ExprList*, int); +int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); +int sqlite3ExprImpliesNonNullRow(Expr*,int); +void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); +void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); +int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); +int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); +Vdbe *sqlite3GetVdbe(Parse*); + +void sqlite3PrngSaveState(void); +void sqlite3PrngRestoreState(void); + +void sqlite3RollbackAll(sqlite3*,int); +void sqlite3CodeVerifySchema(Parse*, int); +void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); +void sqlite3BeginTransaction(Parse*, int); +void sqlite3EndTransaction(Parse*,int); +void sqlite3Savepoint(Parse*, int, Token*); +void sqlite3CloseSavepoints(sqlite3 *); +void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +int sqlite3ExprIdToTrueFalse(Expr*); +int sqlite3ExprTruthValue(const Expr*); +int sqlite3ExprIsConstant(Expr*); +int sqlite3ExprIsConstantNotJoin(Expr*); +int sqlite3ExprIsConstantOrFunction(Expr*, u8); +int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); +int sqlite3ExprIsTableConstant(Expr*,int); + + + +int sqlite3ExprIsInteger(Expr*, int*); +int sqlite3ExprCanBeNull(const Expr*); +int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); +int sqlite3IsRowid(const char*); +void sqlite3GenerateRowDelete( + Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); +void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); +int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); +void sqlite3ResolvePartIdxLabel(Parse*,int); +int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int); +void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, + u8,u8,int,int*,int*,Upsert*); + + + + + +void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); +int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*); +void sqlite3BeginWriteOperation(Parse*, int, int); +void sqlite3MultiWrite(Parse*); +void sqlite3MayAbort(Parse*); +void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); +void sqlite3UniqueConstraint(Parse*, int, Index*); +void sqlite3RowidConstraint(Parse*, int, Table*); +Expr *sqlite3ExprDup(sqlite3*,Expr*,int); +ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); +SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); +IdList *sqlite3IdListDup(sqlite3*,IdList*); +Select *sqlite3SelectDup(sqlite3*,Select*,int); +FuncDef *sqlite3FunctionSearch(int,const char*); +void sqlite3InsertBuiltinFuncs(FuncDef*,int); +FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); +void sqlite3RegisterBuiltinFunctions(void); +void sqlite3RegisterDateTimeFunctions(void); +void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); +int sqlite3SafetyCheckOk(sqlite3*); +int sqlite3SafetyCheckSickOrOk(sqlite3*); +void sqlite3ChangeCookie(Parse*, int); + + +void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); + + + + void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, + Expr*,int, int); + void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); + void sqlite3DropTrigger(Parse*, SrcList*, int); + void sqlite3DropTriggerPtr(Parse*, Trigger*); + Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask); + Trigger *sqlite3TriggerList(Parse *, Table *); + void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, + int, int, int); + void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); + void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); + void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); + TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, + const char*,const char*); + TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*, + Select*,u8,Upsert*, + const char*,const char*); + TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8, + const char*,const char*); + TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*, + const char*,const char*); + void sqlite3DeleteTrigger(sqlite3*, Trigger*); + void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); + u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); +# 4161 "src/sqliteInt.h" +int sqlite3JoinType(Parse*, Token*, Token*, Token*); +void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); +void sqlite3DeferForeignKey(Parse*, int); + + void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); + int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); + void sqlite3AuthContextPush(Parse*, AuthContext*, const char*); + void sqlite3AuthContextPop(AuthContext*); + int sqlite3AuthReadCol(Parse*, const char *, const char *, int); + + + + + + +void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); +void sqlite3Detach(Parse*, Expr*); +void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); +int sqlite3FixSrcList(DbFixer*, SrcList*); +int sqlite3FixSelect(DbFixer*, Select*); +int sqlite3FixExpr(DbFixer*, Expr*); +int sqlite3FixExprList(DbFixer*, ExprList*); +int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); +int sqlite3RealSameAsInt(double,sqlite3_int64); +int sqlite3AtoF(const char *z, double*, int, u8); +int sqlite3GetInt32(const char *, int*); +int sqlite3Atoi(const char*); + +int sqlite3Utf16ByteLen(const void *pData, int nChar); + +int sqlite3Utf8CharLen(const char *pData, int nByte); +u32 sqlite3Utf8Read(const u8**); +LogEst sqlite3LogEst(u64); +LogEst sqlite3LogEstAdd(LogEst,LogEst); + +LogEst sqlite3LogEstFromDouble(double); + + + + + + +VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); +const char *sqlite3VListNumToName(VList*,int); +int sqlite3VListNameToNum(VList*,const char*,int); + + + + + + +int sqlite3PutVarint(unsigned char*, u64); +u8 sqlite3GetVarint(const unsigned char *, u64 *); +u8 sqlite3GetVarint32(const unsigned char *, u32 *); +int sqlite3VarintLen(u64 v); +# 4231 "src/sqliteInt.h" +const char *sqlite3IndexAffinityStr(sqlite3*, Index*); +void sqlite3TableAffinity(Vdbe*, Table*, int); +char sqlite3CompareAffinity(Expr *pExpr, char aff2); +int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); +char sqlite3TableColumnAffinity(Table*,int); +char sqlite3ExprAffinity(Expr *pExpr); +int sqlite3Atoi64(const char*, i64*, int, u8); +int sqlite3DecOrHexToI64(const char*, i64*); +void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); +void sqlite3Error(sqlite3*,int); +void sqlite3SystemError(sqlite3*,int); +void *sqlite3HexToBlob(sqlite3*, const char *z, int n); +u8 sqlite3HexToInt(int h); +int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); +# 4254 "src/sqliteInt.h" +const char *sqlite3ErrStr(int); +int sqlite3ReadSchema(Parse *pParse); +CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); +int sqlite3IsBinary(const CollSeq*); +CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); +CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); +CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr); +int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*); +Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); +Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); +Expr *sqlite3ExprSkipCollate(Expr*); +int sqlite3CheckCollSeq(Parse *, CollSeq *); +int sqlite3WritableSchema(sqlite3*); +int sqlite3CheckObjectName(Parse *, const char *); +void sqlite3VdbeSetChanges(sqlite3 *, int); +int sqlite3AddInt64(i64*,i64); +int sqlite3SubInt64(i64*,i64); +int sqlite3MulInt64(i64*,i64); +int sqlite3AbsInt32(int); + + + + + +u8 sqlite3GetBoolean(const char *z,u8); + +const void *sqlite3ValueText(sqlite3_value*, u8); +int sqlite3ValueBytes(sqlite3_value*, u8); +void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, + void(*)(void*)); +void sqlite3ValueSetNull(sqlite3_value*); +void sqlite3ValueFree(sqlite3_value*); + +void sqlite3ResultIntReal(sqlite3_context*); + +sqlite3_value *sqlite3ValueNew(sqlite3 *); + +char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); + +int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); +void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); + +extern const unsigned char sqlite3OpcodeProperty[]; +extern const char sqlite3StrBINARY[]; +extern const unsigned char sqlite3UpperToLower[]; +extern const unsigned char sqlite3CtypeMap[]; +extern const Token sqlite3IntTokens[]; +extern struct Sqlite3Config sqlite3Config; +extern FuncDefHash sqlite3BuiltinFunctions; + +extern int sqlite3PendingByte; + + + + + +void sqlite3RootPageMoved(sqlite3*, int, int, int); +void sqlite3Reindex(Parse*, Token*, Token*); +void sqlite3AlterFunctions(void); +void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); +void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); +int sqlite3GetToken(const unsigned char *, int *); +void sqlite3NestedParse(Parse*, const char*, ...); +void sqlite3ExpirePreparedStatements(sqlite3*, int); +void sqlite3CodeRhsOfIN(Parse*, Expr*, int); +int sqlite3CodeSubselect(Parse*, Expr*); +void sqlite3SelectPrep(Parse*, Select*, NameContext*); +void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); +int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); +int sqlite3ResolveExprNames(NameContext*, Expr*); +int sqlite3ResolveExprListNames(NameContext*, ExprList*); +void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); +int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); +int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); +void sqlite3ColumnDefault(Vdbe *, Table *, int, int); +void sqlite3AlterFinishAddColumn(Parse *, Token *); +void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +void *sqlite3RenameTokenMap(Parse*, void*, Token*); +void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); +void sqlite3RenameExprUnmap(Parse*, Expr*); +void sqlite3RenameExprlistUnmap(Parse*, ExprList*); +CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); +char sqlite3AffinityType(const char*, Column*); +void sqlite3Analyze(Parse*, Token*, Token*); +int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*); +int sqlite3FindDb(sqlite3*, Token*); +int sqlite3FindDbName(sqlite3 *, const char *); +int sqlite3AnalysisLoad(sqlite3*,int iDB); +void sqlite3DeleteIndexSamples(sqlite3*,Index*); +void sqlite3DefaultRowEst(Index*); +void sqlite3RegisterLikeFunctions(sqlite3*, int); +int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); +void sqlite3SchemaClear(void *); +Schema *sqlite3SchemaGet(sqlite3 *, Btree *); +int sqlite3SchemaToIndex(sqlite3 *db, Schema *); +KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); +void sqlite3KeyInfoUnref(KeyInfo*); +KeyInfo *sqlite3KeyInfoRef(KeyInfo*); +KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); +KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); + + + + +int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*,int,sqlite3_value **), + FuncDestructor *pDestructor +); +void sqlite3NoopDestructor(void*); +void sqlite3OomFault(sqlite3*); +void sqlite3OomClear(sqlite3*); +int sqlite3ApiExit(sqlite3 *db, int); +int sqlite3OpenTempDatabase(Parse *); + +void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); +char *sqlite3StrAccumFinish(StrAccum*); +void sqlite3SelectDestInit(SelectDest*,int,int); +Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); + +void sqlite3BackupRestart(sqlite3_backup *); +void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); + + +int sqlite3ExprCheckIN(Parse*, Expr*); +# 4400 "src/sqliteInt.h" + void *sqlite3ParserAlloc(void*(*)(u64), Parse*); + void sqlite3ParserFree(void*, void(*)(void*)); + +void sqlite3Parser(void*, int, Token); +int sqlite3ParserFallback(int); + + + + +void sqlite3AutoLoadExtensions(sqlite3*); + + void sqlite3CloseExtensions(sqlite3*); + + + + + + void sqlite3TableLock(Parse *, int, int, u8, const char *); +# 4438 "src/sqliteInt.h" + void sqlite3VtabClear(sqlite3 *db, Table*); + void sqlite3VtabDisconnect(sqlite3 *db, Table *p); + int sqlite3VtabSync(sqlite3 *db, Vdbe*); + int sqlite3VtabRollback(sqlite3 *db); + int sqlite3VtabCommit(sqlite3 *db); + void sqlite3VtabLock(VTable *); + void sqlite3VtabUnlock(VTable *); + void sqlite3VtabUnlockList(sqlite3*); + int sqlite3VtabSavepoint(sqlite3 *, int, int); + void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); + VTable *sqlite3GetVTable(sqlite3*, Table*); + Module *sqlite3VtabCreateModule( + sqlite3*, + const char*, + const sqlite3_module*, + void*, + void(*)(void*) + ); + + +int sqlite3VtabEponymousTableInit(Parse*,Module*); +void sqlite3VtabEponymousTableClear(sqlite3*,Module*); +void sqlite3VtabMakeWritable(Parse*,Table*); +void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); +void sqlite3VtabFinishParse(Parse*, Token*); +void sqlite3VtabArgInit(Parse*); +void sqlite3VtabArgExtend(Parse*, Token*); +int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); +int sqlite3VtabCallConnect(Parse*, Table*); +int sqlite3VtabCallDestroy(sqlite3*, int, const char *); +int sqlite3VtabBegin(sqlite3 *, VTable *); +FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); +sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); +int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); +int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); +void sqlite3ParserReset(Parse*); + + + +int sqlite3Reprepare(Vdbe*); +void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); +CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); +int sqlite3TempInMemory(const sqlite3*); +const char *sqlite3JournalModename(int); + + int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); + int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); + + + With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); + void sqlite3WithDelete(sqlite3*,With*); + void sqlite3WithPush(Parse*, With*, u8); + + + + + + Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); + void sqlite3UpsertDelete(sqlite3*,Upsert*); + Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); + int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); + void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); +# 4515 "src/sqliteInt.h" + void sqlite3FkCheck(Parse*, Table*, int, int, int*, int); + void sqlite3FkDropTable(Parse*, SrcList *, Table*); + void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); + int sqlite3FkRequired(Parse*, Table*, int*, int); + u32 sqlite3FkOldmask(Parse*, Table*); + FKey *sqlite3FkReferences(Table *); +# 4530 "src/sqliteInt.h" + void sqlite3FkDelete(sqlite3 *, Table*); + int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); +# 4550 "src/sqliteInt.h" + void sqlite3BeginBenignMalloc(void); + void sqlite3EndBenignMalloc(void); +# 4571 "src/sqliteInt.h" +int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); + +int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); +int sqlite3JournalSize(sqlite3_vfs *); + + + + + +int sqlite3JournalIsInMemory(sqlite3_file *p); +void sqlite3MemJournalOpen(sqlite3_file *); + +void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); + + int sqlite3SelectExprHeight(Select *); + int sqlite3ExprCheckHeight(Parse*, int); + + + + + +u32 sqlite3Get4byte(const u8*); +void sqlite3Put4byte(u8*, u32); +# 4671 "src/sqliteInt.h" +int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); +int sqlite3ThreadJoin(SQLiteThread*, void**); +# 4682 "src/sqliteInt.h" +int sqlite3ExprVectorSize(Expr *pExpr); +int sqlite3ExprIsVector(Expr *pExpr); +Expr *sqlite3VectorFieldSubexpr(Expr*, int); +Expr *sqlite3ExprForVectorField(Parse*,Expr*,int); +void sqlite3VectorErrorMsg(Parse*, Expr*); + + +const char **sqlite3CompileOptions(int *pnOpt); +# 217 "src/btreeInt.h" 2 +# 232 "src/btreeInt.h" +typedef struct MemPage MemPage; +typedef struct BtLock BtLock; +typedef struct CellInfo CellInfo; +# 273 "src/btreeInt.h" +struct MemPage { + u8 isInit; + u8 bBusy; + u8 intKey; + u8 intKeyLeaf; + Pgno pgno; + + + u8 leaf; + u8 hdrOffset; + u8 childPtrSize; + u8 max1bytePayload; + u8 nOverflow; + u16 maxLocal; + u16 minLocal; + u16 cellOffset; + int nFree; + u16 nCell; + u16 maskPage; + u16 aiOvfl[4]; + + u8 *apOvfl[4]; + BtShared *pBt; + u8 *aData; + u8 *aDataEnd; + u8 *aCellIdx; + u8 *aDataOfst; + DbPage *pDbPage; + u16 (*xCellSize)(MemPage*,u8*); + void (*xParseCell)(MemPage*,u8*,CellInfo*); +}; +# 312 "src/btreeInt.h" +struct BtLock { + Btree *pBtree; + Pgno iTable; + u8 eLock; + BtLock *pNext; +}; +# 344 "src/btreeInt.h" +struct Btree { + sqlite3 *db; + BtShared *pBt; + u8 inTrans; + u8 sharable; + u8 locked; + u8 hasIncrblobCur; + int wantToLock; + int nBackup; + u32 iDataVersion; + Btree *pNext; + Btree *pPrev; + + BtLock lock; + +}; +# 407 "src/btreeInt.h" +struct BtShared { + Pager *pPager; + sqlite3 *db; + BtCursor *pCursor; + MemPage *pPage1; + u8 openFlags; + + u8 autoVacuum; + u8 incrVacuum; + u8 bDoTruncate; + + u8 inTransaction; + u8 max1bytePayload; + + + + u16 btsFlags; + u16 maxLocal; + u16 minLocal; + u16 maxLeaf; + u16 minLeaf; + u32 pageSize; + u32 usableSize; + int nTransaction; + u32 nPage; + void *pSchema; + void (*xFreeSchema)(void*); + sqlite3_mutex *mutex; + Bitvec *pHasContent; + + int nRef; + BtShared *pNext; + BtLock *pLock; + Btree *pWriter; + + u8 *pTmpSpace; +}; +# 463 "src/btreeInt.h" +struct CellInfo { + i64 nKey; + u8 *pPayload; + u32 nPayload; + u16 nLocal; + u16 nSize; +}; +# 508 "src/btreeInt.h" +struct BtCursor { + u8 eState; + u8 curFlags; + u8 curPagerFlags; + u8 hints; + int skipNext; + + Btree *pBtree; + Pgno *aOverflow; + void *pKey; + + + + + BtShared *pBt; + BtCursor *pNext; + CellInfo info; + i64 nKey; + Pgno pgnoRoot; + i8 iPage; + u8 curIntKey; + u16 ix; + u16 aiIdx[20 -1]; + struct KeyInfo *pKeyInfo; + MemPage *pPage; + MemPage *apPage[20 -1]; +}; +# 675 "src/btreeInt.h" +typedef struct IntegrityCk IntegrityCk; +struct IntegrityCk { + BtShared *pBt; + Pager *pPager; + u8 *aPgRef; + Pgno nPage; + int mxErr; + int nErr; + int mallocFailed; + const char *zPfx; + int v1, v2; + StrAccum errMsg; + u32 *heap; +}; +# 17 "src/btree.c" 2 + + + + + +static const char zMagicHeader[] = "SQLite format 3"; +# 77 "src/btree.c" +static BtShared * sqlite3SharedCacheList = 0; +# 89 "src/btree.c" +int sqlite3_enable_shared_cache(int enable){ + sqlite3Config.sharedCacheEnabled = enable; + return 0; +} +# 275 "src/btree.c" +static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==1 || eLock==2 ); + assert( p->db!=0 ); + assert( !(p->db->flags&0x00000400)||eLock==2||iTab==1 ); + + + + + + assert( eLock==1 || (p==pBt->pWriter && p->inTrans==2) ); + assert( eLock==1 || pBt->inTransaction==2 ); + + + if( !p->sharable ){ + return 0; + } + + + + + if( pBt->pWriter!=p && (pBt->btsFlags & 0x0040)!=0 ){ + ; + return (6 | (1<<8)); + } + + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ +# 314 "src/btree.c" + assert( pIter->eLock==1 || pIter->eLock==2 ); + assert( eLock==1 || pIter->pBtree==p || pIter->eLock==1); + if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ + ; + if( eLock==2 ){ + assert( p==pBt->pWriter ); + pBt->btsFlags |= 0x0080; + } + return (6 | (1<<8)); + } + } + return 0; +} +# 347 "src/btree.c" +static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ + BtShared *pBt = p->pBt; + BtLock *pLock = 0; + BtLock *pIter; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( eLock==1 || eLock==2 ); + assert( p->db!=0 ); + + + + + + assert( 0==(p->db->flags&0x00000400) || eLock==2 ); + + + + assert( p->sharable ); + assert( 0==querySharedCacheTableLock(p, iTable, eLock) ); + + + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->iTable==iTable && pIter->pBtree==p ){ + pLock = pIter; + break; + } + } + + + + + if( !pLock ){ + pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); + if( !pLock ){ + return 7; + } + pLock->iTable = iTable; + pLock->pBtree = p; + pLock->pNext = pBt->pLock; + pBt->pLock = pLock; + } + + + + + + assert( 2>1 ); + if( eLock>pLock->eLock ){ + pLock->eLock = eLock; + } + + return 0; +} +# 411 "src/btree.c" +static void clearAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + BtLock **ppIter = &pBt->pLock; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->sharable || 0==*ppIter ); + assert( p->inTrans>0 ); + + while( *ppIter ){ + BtLock *pLock = *ppIter; + assert( (pBt->btsFlags & 0x0040)==0 || pBt->pWriter==pLock->pBtree ); + assert( pLock->pBtree->inTrans>=pLock->eLock ); + if( pLock->pBtree==p ){ + *ppIter = pLock->pNext; + assert( pLock->iTable!=1 || pLock==&p->lock ); + if( pLock->iTable!=1 ){ + sqlite3_free(pLock); + } + }else{ + ppIter = &pLock->pNext; + } + } + + assert( (pBt->btsFlags & 0x0080)==0 || pBt->pWriter ); + if( pBt->pWriter==p ){ + pBt->pWriter = 0; + pBt->btsFlags &= ~(0x0040|0x0080); + }else if( pBt->nTransaction==2 ){ +# 448 "src/btree.c" + pBt->btsFlags &= ~0x0080; + } +} + + + + +static void downgradeAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + if( pBt->pWriter==p ){ + BtLock *pLock; + pBt->pWriter = 0; + pBt->btsFlags &= ~(0x0040|0x0080); + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + assert( pLock->eLock==1 || pLock->pBtree==p ); + pLock->eLock = 1; + } + } +} + + + +static void releasePage(MemPage *pPage); +static void releasePageOne(MemPage *pPage); +static void releasePageNotNull(MemPage *pPage); +# 508 "src/btree.c" +static void invalidateAllOverflowCache(BtShared *pBt){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + for(p=pBt->pCursor; p; p=p->pNext){ + (p->curFlags &= ~0x04); + } +} +# 530 "src/btree.c" +static void invalidateIncrblobCursors( + Btree *pBtree, + Pgno pgnoRoot, + i64 iRow, + int isClearTable +){ + BtCursor *p; + if( pBtree->hasIncrblobCur==0 ) return; + assert( sqlite3BtreeHoldsMutex(pBtree) ); + pBtree->hasIncrblobCur = 0; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( (p->curFlags & 0x10)!=0 ){ + pBtree->hasIncrblobCur = 1; + if( p->pgnoRoot==pgnoRoot && (isClearTable || p->info.nKey==iRow) ){ + p->eState = 1; + } + } + } +} +# 590 "src/btree.c" +static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ + int rc = 0; + if( !pBt->pHasContent ){ + assert( pgno<=pBt->nPage ); + pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); + if( !pBt->pHasContent ){ + rc = 7; + } + } + if( rc==0 && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ + rc = sqlite3BitvecSet(pBt->pHasContent, pgno); + } + return rc; +} +# 612 "src/btree.c" +static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ + Bitvec *p = pBt->pHasContent; + return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno))); +} + + + + + +static void btreeClearHasContent(BtShared *pBt){ + sqlite3BitvecDestroy(pBt->pHasContent); + pBt->pHasContent = 0; +} + + + + +static void btreeReleaseAllCursorPages(BtCursor *pCur){ + int i; + if( pCur->iPage>=0 ){ + for(i=0; i<pCur->iPage; i++){ + releasePageNotNull(pCur->apPage[i]); + } + releasePageNotNull(pCur->pPage); + pCur->iPage = -1; + } +} +# 653 "src/btree.c" +static int saveCursorKey(BtCursor *pCur){ + int rc = 0; + assert( 0==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + if( pCur->curIntKey ){ + + pCur->nKey = sqlite3BtreeIntegerKey(pCur); + }else{ + + + + + + + void *pKey; + pCur->nKey = sqlite3BtreePayloadSize(pCur); + pKey = sqlite3Malloc( pCur->nKey + 9 + 8 ); + if( pKey ){ + rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); + if( rc==0 ){ + memset(((u8*)pKey)+pCur->nKey, 0, 9+8); + pCur->pKey = pKey; + }else{ + sqlite3_free(pKey); + } + }else{ + rc = 7; + } + } + assert( !pCur->curIntKey || !pCur->pKey ); + return rc; +} +# 695 "src/btree.c" +static int saveCursorPosition(BtCursor *pCur){ + int rc; + + assert( 0==pCur->eState || 2==pCur->eState ); + assert( 0==pCur->pKey ); + assert( cursorHoldsMutex(pCur) ); + + if( pCur->eState==2 ){ + pCur->eState = 0; + }else{ + pCur->skipNext = 0; + } + + rc = saveCursorKey(pCur); + if( rc==0 ){ + btreeReleaseAllCursorPages(pCur); + pCur->eState = 3; + } + + pCur->curFlags &= ~(0x02|0x04|0x08); + return rc; +} + + +static int saveCursorsOnList(BtCursor*,Pgno,BtCursor*); +# 742 "src/btree.c" +static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ + BtCursor *p; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pExcept==0 || pExcept->pBt==pBt ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break; + } + if( p ) return saveCursorsOnList(p, iRoot, pExcept); + if( pExcept ) pExcept->curFlags &= ~0x20; + return 0; +} + + + + + + +static int saveCursorsOnList( + BtCursor *p, + Pgno iRoot, + BtCursor *pExcept +){ + do{ + if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){ + if( p->eState==0 || p->eState==2 ){ + int rc = saveCursorPosition(p); + if( 0!=rc ){ + return rc; + } + }else{ + ; + btreeReleaseAllCursorPages(p); + } + } + p = p->pNext; + }while( p ); + return 0; +} + + + + +void sqlite3BtreeClearCursor(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + pCur->eState = 1; +} + + + + + + +static int btreeMoveto( + BtCursor *pCur, + const void *pKey, + i64 nKey, + int bias, + int *pRes +){ + int rc; + UnpackedRecord *pIdxKey; + + if( pKey ){ + KeyInfo *pKeyInfo = pCur->pKeyInfo; + assert( nKey==(i64)(int)nKey ); + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); + if( pIdxKey==0 ) return 7; + sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); + if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ + rc = sqlite3CorruptError(813); + goto moveto_done; + } + }else{ + pIdxKey = 0; + } + rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); +moveto_done: + if( pIdxKey ){ + sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); + } + return rc; +} +# 834 "src/btree.c" +static int btreeRestoreCursorPosition(BtCursor *pCur){ + int rc; + int skipNext = 0; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState>=3 ); + if( pCur->eState==4 ){ + return pCur->skipNext; + } + pCur->eState = 1; + if( sqlite3FaultSim(410) ){ + rc = 10; + }else{ + rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext); + } + if( rc==0 ){ + sqlite3_free(pCur->pKey); + pCur->pKey = 0; + assert( pCur->eState==0 || pCur->eState==1 ); + if( skipNext ) pCur->skipNext = skipNext; + if( pCur->skipNext && pCur->eState==0 ){ + pCur->eState = 2; + } + } + return rc; +} +# 877 "src/btree.c" +int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ + assert( ((((char*)(pCur) - (char*)0)&7)==0) + || pCur==sqlite3BtreeFakeValidCursor() ); + assert( ((int)((char*)&((BtCursor*)0)->eState))==0 ); + assert( sizeof(pCur->eState)==1 ); + return 0 != *(u8*)pCur; +} + + + + + + +BtCursor *sqlite3BtreeFakeValidCursor(void){ + static u8 fakeCursor = 0; + assert( ((int)((char*)&((BtCursor*)0)->eState))==0 ); + return (BtCursor*)&fakeCursor; +} +# 909 "src/btree.c" +int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ + int rc; + + assert( pCur!=0 ); + assert( pCur->eState!=0 ); + rc = (pCur->eState>=3 ? btreeRestoreCursorPosition(pCur) : 0); + if( rc ){ + *pDifferentRow = 1; + return rc; + } + if( pCur->eState!=0 ){ + *pDifferentRow = 1; + }else{ + *pDifferentRow = 0; + } + return 0; +} +# 941 "src/btree.c" +void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ + assert( x==0x00000002 || x==0x00000001 || x==0 ); + pCur->hints = x; +} +# 957 "src/btree.c" +static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ + int nPagesPerMapPage; + Pgno iPtrMap, ret; + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno<2 ) return 0; + nPagesPerMapPage = (pBt->usableSize/5)+1; + iPtrMap = (pgno-2)/nPagesPerMapPage; + ret = (iPtrMap*nPagesPerMapPage) + 2; + if( ret==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ + ret++; + } + return ret; +} +# 981 "src/btree.c" +static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ + DbPage *pDbPage; + u8 *pPtrmap; + Pgno iPtrmap; + int offset; + int rc; + + if( *pRC ) return; + + assert( sqlite3_mutex_held(pBt->mutex) ); + + assert( 0==(ptrmapPageno((pBt), (((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1))))==(((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)))) ); + + assert( pBt->autoVacuum ); + if( key==0 ){ + *pRC = sqlite3CorruptError(996); + return; + } + iPtrmap = ptrmapPageno(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + if( rc!=0 ){ + *pRC = rc; + return; + } + if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){ + + + + *pRC = sqlite3CorruptError(1009); + goto ptrmap_exit; + } + offset = (5*(key-iPtrmap-1)); + if( offset<0 ){ + *pRC = sqlite3CorruptError(1014); + goto ptrmap_exit; + } + assert( offset <= (int)pBt->usableSize-5 ); + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + if( eType!=pPtrmap[offset] || sqlite3Get4byte(&pPtrmap[offset+1])!=parent ){ + ; + *pRC= rc = sqlite3PagerWrite(pDbPage); + if( rc==0 ){ + pPtrmap[offset] = eType; + sqlite3Put4byte(&pPtrmap[offset+1], parent); + } + } + +ptrmap_exit: + sqlite3PagerUnref(pDbPage); +} +# 1040 "src/btree.c" +static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ + DbPage *pDbPage; + int iPtrmap; + u8 *pPtrmap; + int offset; + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + + iPtrmap = ptrmapPageno(pBt, key); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + if( rc!=0 ){ + return rc; + } + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); + + offset = (5*(key-iPtrmap-1)); + if( offset<0 ){ + sqlite3PagerUnref(pDbPage); + return sqlite3CorruptError(1059); + } + assert( offset <= (int)pBt->usableSize-5 ); + assert( pEType!=0 ); + *pEType = pPtrmap[offset]; + if( pPgno ) *pPgno = sqlite3Get4byte(&pPtrmap[offset+1]); + + sqlite3PagerUnref(pDbPage); + if( *pEType<1 || *pEType>5 ) return sqlite3CorruptError(1067); + return 0; +} +# 1099 "src/btree.c" +static void btreeParseCellAdjustSizeForOverflow( + MemPage *pPage, + u8 *pCell, + CellInfo *pInfo +){ +# 1113 "src/btree.c" + int minLocal; + int maxLocal; + int surplus; + + minLocal = pPage->minLocal; + maxLocal = pPage->maxLocal; + surplus = minLocal + (pInfo->nPayload - minLocal)%(pPage->pBt->usableSize-4); + ; + ; + if( surplus <= maxLocal ){ + pInfo->nLocal = (u16)surplus; + }else{ + pInfo->nLocal = (u16)minLocal; + } + pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4; +} +# 1144 "src/btree.c" +static void btreeParseCellPtrNoPayload( + MemPage *pPage, + u8 *pCell, + CellInfo *pInfo +){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 ); + assert( pPage->childPtrSize==4 ); + + (void)(pPage); + + pInfo->nSize = 4 + sqlite3GetVarint(&pCell[4], (u64*)&pInfo->nKey); + pInfo->nPayload = 0; + pInfo->nLocal = 0; + pInfo->pPayload = 0; + return; +} +static void btreeParseCellPtr( + MemPage *pPage, + u8 *pCell, + CellInfo *pInfo +){ + u8 *pIter; + u32 nPayload; + u64 iKey; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 || pPage->leaf==1 ); + assert( pPage->intKeyLeaf ); + assert( pPage->childPtrSize==0 ); + pIter = pCell; + + + + + + + + nPayload = *pIter; + if( nPayload>=0x80 ){ + u8 *pEnd = &pIter[8]; + nPayload &= 0x7f; + do{ + nPayload = (nPayload<<7) | (*++pIter & 0x7f); + }while( (*pIter)>=0x80 && pIter<pEnd ); + } + pIter++; + + + + + + + + iKey = *pIter; + if( iKey>=0x80 ){ + u8 *pEnd = &pIter[7]; + iKey &= 0x7f; + while(1){ + iKey = (iKey<<7) | (*++pIter & 0x7f); + if( (*pIter)<0x80 ) break; + if( pIter>=pEnd ){ + iKey = (iKey<<8) | *++pIter; + break; + } + } + } + pIter++; + + pInfo->nKey = *(i64*)&iKey; + pInfo->nPayload = nPayload; + pInfo->pPayload = pIter; + ; + ; + if( nPayload<=pPage->maxLocal ){ + + + + pInfo->nSize = nPayload + (u16)(pIter - pCell); + if( pInfo->nSize<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + }else{ + btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); + } +} +static void btreeParseCellPtrIndex( + MemPage *pPage, + u8 *pCell, + CellInfo *pInfo +){ + u8 *pIter; + u32 nPayload; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->leaf==0 || pPage->leaf==1 ); + assert( pPage->intKeyLeaf==0 ); + pIter = pCell + pPage->childPtrSize; + nPayload = *pIter; + if( nPayload>=0x80 ){ + u8 *pEnd = &pIter[8]; + nPayload &= 0x7f; + do{ + nPayload = (nPayload<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pIter<pEnd ); + } + pIter++; + pInfo->nKey = nPayload; + pInfo->nPayload = nPayload; + pInfo->pPayload = pIter; + ; + ; + if( nPayload<=pPage->maxLocal ){ + + + + pInfo->nSize = nPayload + (u16)(pIter - pCell); + if( pInfo->nSize<4 ) pInfo->nSize = 4; + pInfo->nLocal = (u16)nPayload; + }else{ + btreeParseCellAdjustSizeForOverflow(pPage, pCell, pInfo); + } +} +static void btreeParseCell( + MemPage *pPage, + int iCell, + CellInfo *pInfo +){ + pPage->xParseCell(pPage, ((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(iCell)])))), pInfo); +} +# 1286 "src/btree.c" +static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + pPage->childPtrSize; + u8 *pEnd; + u32 nSize; +# 1300 "src/btree.c" + nSize = *pIter; + if( nSize>=0x80 ){ + pEnd = &pIter[8]; + nSize &= 0x7f; + do{ + nSize = (nSize<<7) | (*++pIter & 0x7f); + }while( *(pIter)>=0x80 && pIter<pEnd ); + } + pIter++; + if( pPage->intKey ){ + + + + pEnd = &pIter[9]; + while( (*pIter++)&0x80 && pIter<pEnd ); + } + ; + ; + if( nSize<=pPage->maxLocal ){ + nSize += (u32)(pIter - pCell); + if( nSize<4 ) nSize = 4; + }else{ + int minLocal = pPage->minLocal; + nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + ; + ; + if( nSize>pPage->maxLocal ){ + nSize = minLocal; + } + nSize += 4 + (u16)(pIter - pCell); + } + assert( nSize==debuginfo.nSize || (sqlite3Config.neverCorrupt==0) ); + return (u16)nSize; +} +static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){ + u8 *pIter = pCell + 4; + u8 *pEnd; +# 1346 "src/btree.c" + (void)(pPage); + + + assert( pPage->childPtrSize==4 ); + pEnd = pIter + 9; + while( (*pIter++)&0x80 && pIter<pEnd ); + assert( debuginfo.nSize==(u16)(pIter - pCell) || (sqlite3Config.neverCorrupt==0) ); + return (u16)(pIter - pCell); +} +# 1372 "src/btree.c" +static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ + CellInfo info; + if( *pRC ) return; + assert( pCell!=0 ); + pPage->xParseCell(pPage, pCell, &info); + if( info.nLocal<info.nPayload ){ + Pgno ovfl; + if( (((uptr)(pSrc->aDataEnd)>=(uptr)(pCell))&&((uptr)(pSrc->aDataEnd)<(uptr)(pCell+info.nLocal))) ){ + ; + *pRC = sqlite3CorruptError(1381); + return; + } + ovfl = sqlite3Get4byte(&pCell[info.nSize-4]); + ptrmapPut(pPage->pBt, ovfl, 3, pPage->pgno, pRC); + } +} +# 1403 "src/btree.c" +static int defragmentPage(MemPage *pPage, int nMaxFrag){ + int i; + int pc; + int hdr; + int size; + int usableSize; + int cellOffset; + int cbrk; + int nCell; + unsigned char *data; + unsigned char *temp; + unsigned char *src; + int iCellFirst; + int iCellLast; + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt!=0 ); + assert( pPage->pBt->usableSize <= 65536 ); + assert( pPage->nOverflow==0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + temp = 0; + src = data = pPage->aData; + hdr = pPage->hdrOffset; + cellOffset = pPage->cellOffset; + nCell = pPage->nCell; + assert( nCell==((&data[hdr+3])[0]<<8 | (&data[hdr+3])[1]) || (sqlite3Config.neverCorrupt==0) ); + iCellFirst = cellOffset + 2*nCell; + usableSize = pPage->pBt->usableSize; + + + + + + + if( (int)data[hdr+7]<=nMaxFrag ){ + int iFree = ((&data[hdr+1])[0]<<8 | (&data[hdr+1])[1]); + if( iFree>usableSize-4 ) return sqlite3CorruptError(1439); + if( iFree ){ + int iFree2 = ((&data[iFree])[0]<<8 | (&data[iFree])[1]); + if( iFree2>usableSize-4 ) return sqlite3CorruptError(1442); + if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ + u8 *pEnd = &data[cellOffset + nCell*2]; + u8 *pAddr; + int sz2 = 0; + int sz = ((&data[iFree+2])[0]<<8 | (&data[iFree+2])[1]); + int top = ((&data[hdr+5])[0]<<8 | (&data[hdr+5])[1]); + if( top>=iFree ){ + return sqlite3CorruptError(1450); + } + if( iFree2 ){ + if( iFree+sz>iFree2 ) return sqlite3CorruptError(1453); + sz2 = ((&data[iFree2+2])[0]<<8 | (&data[iFree2+2])[1]); + if( iFree2+sz2 > usableSize ) return sqlite3CorruptError(1455); + memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); + sz += sz2; + }else if( iFree+sz>usableSize ){ + return sqlite3CorruptError(1459); + } + + cbrk = top+sz; + assert( cbrk+(iFree-top) <= usableSize ); + memmove(&data[cbrk], &data[top], iFree-top); + for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){ + pc = ((pAddr)[0]<<8 | (pAddr)[1]); + if( pc<iFree ){ ((pAddr)[0] = (u8)((pc+sz)>>8), (pAddr)[1] = (u8)(pc+sz)); } + else if( pc<iFree2 ){ ((pAddr)[0] = (u8)((pc+sz2)>>8), (pAddr)[1] = (u8)(pc+sz2)); } + } + goto defragment_out; + } + } + } + + cbrk = usableSize; + iCellLast = usableSize - 4; + for(i=0; i<nCell; i++){ + u8 *pAddr; + pAddr = &data[cellOffset + i*2]; + pc = ((pAddr)[0]<<8 | (pAddr)[1]); + ; + ; + + + + if( pc<iCellFirst || pc>iCellLast ){ + return sqlite3CorruptError(1487); + } + assert( pc>=iCellFirst && pc<=iCellLast ); + size = pPage->xCellSize(pPage, &src[pc]); + cbrk -= size; + if( cbrk<iCellFirst || pc+size>usableSize ){ + return sqlite3CorruptError(1493); + } + assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); + ; + ; + ((pAddr)[0] = (u8)((cbrk)>>8), (pAddr)[1] = (u8)(cbrk)); + if( temp==0 ){ + int x; + if( cbrk==pc ) continue; + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); + x = ((&data[hdr+5])[0]<<8 | (&data[hdr+5])[1]); + memcpy(&temp[x], &data[x], (cbrk+size) - x); + src = temp; + } + memcpy(&data[cbrk], &src[pc], size); + } + data[hdr+7] = 0; + + defragment_out: + assert( pPage->nFree>=0 ); + if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){ + return sqlite3CorruptError(1514); + } + assert( cbrk>=iCellFirst ); + ((&data[hdr+5])[0] = (u8)((cbrk)>>8), (&data[hdr+5])[1] = (u8)(cbrk)); + data[hdr+1] = 0; + data[hdr+2] = 0; + memset(&data[iCellFirst], 0, cbrk-iCellFirst); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + return 0; +} +# 1539 "src/btree.c" +static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ + const int hdr = pPg->hdrOffset; + u8 * const aData = pPg->aData; + int iAddr = hdr + 1; + int pc = ((&aData[iAddr])[0]<<8 | (&aData[iAddr])[1]); + int x; + int maxPC = pPg->pBt->usableSize - nByte; + int size; + + assert( pc>0 ); + while( pc<=maxPC ){ + + + + size = ((&aData[pc+2])[0]<<8 | (&aData[pc+2])[1]); + if( (x = size - nByte)>=0 ){ + ; + ; + if( x<4 ){ + + + if( aData[hdr+7]>57 ) return 0; + + + + memcpy(&aData[iAddr], &aData[pc], 2); + aData[hdr+7] += (u8)x; + }else if( x+pc > maxPC ){ + + *pRc = sqlite3CorruptError(1568); + return 0; + }else{ + + + ((&aData[pc+2])[0] = (u8)((x)>>8), (&aData[pc+2])[1] = (u8)(x)); + } + return &aData[pc + x]; + } + iAddr = pc; + pc = ((&aData[pc])[0]<<8 | (&aData[pc])[1]); + if( pc<=iAddr+size ){ + if( pc ){ + + *pRc = sqlite3CorruptError(1582); + } + return 0; + } + } + if( pc>maxPC+nByte-4 ){ + + *pRc = sqlite3CorruptError(1589); + } + return 0; +} +# 1607 "src/btree.c" +static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ + const int hdr = pPage->hdrOffset; + u8 * const data = pPage->aData; + int top; + int rc = 0; + int gap; + + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( pPage->pBt ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( nByte>=0 ); + assert( pPage->nFree>=nByte ); + assert( pPage->nOverflow==0 ); + assert( nByte < (int)(pPage->pBt->usableSize-8) ); + + assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); + gap = pPage->cellOffset + 2*pPage->nCell; + assert( gap<=65536 ); + + + + + + top = ((&data[hdr+5])[0]<<8 | (&data[hdr+5])[1]); + assert( top<=(int)pPage->pBt->usableSize ); + if( gap>top ){ + if( top==0 && pPage->pBt->usableSize==65536 ){ + top = 65536; + }else{ + return sqlite3CorruptError(1636); + } + } + + + + + + ; + ; + ; + if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){ + u8 *pSpace = pageFindSlot(pPage, nByte, &rc); + if( pSpace ){ + assert( pSpace>=data && (pSpace - data)<65536 ); + *pIdx = (int)(pSpace - data); + return 0; + }else if( rc ){ + return rc; + } + } + + + + + ; + if( gap+2+nByte>top ){ + assert( pPage->nCell>0 || (sqlite3Config.neverCorrupt==0) ); + assert( pPage->nFree>=0 ); + rc = defragmentPage(pPage, ((4)<(pPage->nFree - (2+nByte))?(4):(pPage->nFree - (2+nByte)))); + if( rc ) return rc; + top = (((((int)((&data[hdr+5])[0]<<8 | (&data[hdr+5])[1]))-1)&0xffff)+1); + assert( gap+2+nByte<=top ); + } +# 1678 "src/btree.c" + top -= nByte; + ((&data[hdr+5])[0] = (u8)((top)>>8), (&data[hdr+5])[1] = (u8)(top)); + assert( top+nByte <= (int)pPage->pBt->usableSize ); + *pIdx = top; + return 0; +} +# 1698 "src/btree.c" +static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ + u16 iPtr; + u16 iFreeBlk; + u8 hdr; + u8 nFrag = 0; + u16 iOrigSize = iSize; + u16 x; + u32 iEnd = iStart + iSize; + unsigned char *data = pPage->aData; + + assert( pPage->pBt!=0 ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( (sqlite3Config.neverCorrupt==0) || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); + assert( (sqlite3Config.neverCorrupt==0) || iEnd <= pPage->pBt->usableSize ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( iSize>=4 ); + assert( iStart<=pPage->pBt->usableSize-4 ); + + + + + hdr = pPage->hdrOffset; + iPtr = hdr + 1; + if( data[iPtr+1]==0 && data[iPtr]==0 ){ + iFreeBlk = 0; + }else{ + while( (iFreeBlk = ((&data[iPtr])[0]<<8 | (&data[iPtr])[1]))<iStart ){ + if( iFreeBlk<iPtr+4 ){ + if( iFreeBlk==0 ) break; + return sqlite3CorruptError(1727); + } + iPtr = iFreeBlk; + } + if( iFreeBlk>pPage->pBt->usableSize-4 ){ + return sqlite3CorruptError(1732); + } + assert( iFreeBlk>iPtr || iFreeBlk==0 ); + + + + + + + + if( iFreeBlk && iEnd+3>=iFreeBlk ){ + nFrag = iFreeBlk - iEnd; + if( iEnd>iFreeBlk ) return sqlite3CorruptError(1744); + iEnd = iFreeBlk + ((&data[iFreeBlk+2])[0]<<8 | (&data[iFreeBlk+2])[1]); + if( iEnd > pPage->pBt->usableSize ){ + return sqlite3CorruptError(1747); + } + iSize = iEnd - iStart; + iFreeBlk = ((&data[iFreeBlk])[0]<<8 | (&data[iFreeBlk])[1]); + } + + + + + + if( iPtr>hdr+1 ){ + int iPtrEnd = iPtr + ((&data[iPtr+2])[0]<<8 | (&data[iPtr+2])[1]); + if( iPtrEnd+3>=iStart ){ + if( iPtrEnd>iStart ) return sqlite3CorruptError(1760); + nFrag += iStart - iPtrEnd; + iSize = iEnd - iPtr; + iStart = iPtr; + } + } + if( nFrag>data[hdr+7] ) return sqlite3CorruptError(1766); + data[hdr+7] -= nFrag; + } + x = ((&data[hdr+5])[0]<<8 | (&data[hdr+5])[1]); + if( iStart<=x ){ + + + + if( iStart<x || iPtr!=hdr+1 ) return sqlite3CorruptError(1774); + ((&data[hdr+1])[0] = (u8)((iFreeBlk)>>8), (&data[hdr+1])[1] = (u8)(iFreeBlk)); + ((&data[hdr+5])[0] = (u8)((iEnd)>>8), (&data[hdr+5])[1] = (u8)(iEnd)); + }else{ + + ((&data[iPtr])[0] = (u8)((iStart)>>8), (&data[iPtr])[1] = (u8)(iStart)); + } + if( pPage->pBt->btsFlags & 0x000c ){ + + + memset(&data[iStart], 0, iSize); + } + ((&data[iStart])[0] = (u8)((iFreeBlk)>>8), (&data[iStart])[1] = (u8)(iFreeBlk)); + ((&data[iStart+2])[0] = (u8)((iSize)>>8), (&data[iStart+2])[1] = (u8)(iSize)); + pPage->nFree += iOrigSize; + return 0; +} +# 1804 "src/btree.c" +static int decodeFlags(MemPage *pPage, int flagByte){ + BtShared *pBt; + + assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->leaf = (u8)(flagByte>>3); assert( 0x08 == 1<<3 ); + flagByte &= ~0x08; + pPage->childPtrSize = 4-4*pPage->leaf; + pPage->xCellSize = cellSizePtr; + pBt = pPage->pBt; + if( flagByte==(0x04 | 0x01) ){ + + + assert( (0x04|0x01)==5 ); + + + assert( (0x04|0x01|0x08)==13 ); + pPage->intKey = 1; + if( pPage->leaf ){ + pPage->intKeyLeaf = 1; + pPage->xParseCell = btreeParseCellPtr; + }else{ + pPage->intKeyLeaf = 0; + pPage->xCellSize = cellSizePtrNoPayload; + pPage->xParseCell = btreeParseCellPtrNoPayload; + } + pPage->maxLocal = pBt->maxLeaf; + pPage->minLocal = pBt->minLeaf; + }else if( flagByte==0x02 ){ + + + assert( (0x02)==2 ); + + + assert( (0x02|0x08)==10 ); + pPage->intKey = 0; + pPage->intKeyLeaf = 0; + pPage->xParseCell = btreeParseCellPtrIndex; + pPage->maxLocal = pBt->maxLocal; + pPage->minLocal = pBt->minLocal; + }else{ + + + return sqlite3CorruptError(1847); + } + pPage->max1bytePayload = pBt->max1bytePayload; + return 0; +} + + + + + +static int btreeComputeFreeSpace(MemPage *pPage){ + int pc; + u8 hdr; + u8 *data; + int usableSize; + int nFree; + int top; + int iCellFirst; + int iCellLast; + + assert( pPage->pBt!=0 ); + assert( pPage->pBt->db!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + assert( pPage->isInit==1 ); + assert( pPage->nFree<0 ); + + usableSize = pPage->pBt->usableSize; + hdr = pPage->hdrOffset; + data = pPage->aData; + + + + top = (((((int)((&data[hdr+5])[0]<<8 | (&data[hdr+5])[1]))-1)&0xffff)+1); + iCellFirst = hdr + 8 + pPage->childPtrSize + 2*pPage->nCell; + iCellLast = usableSize - 4; + + + + + + pc = ((&data[hdr+1])[0]<<8 | (&data[hdr+1])[1]); + nFree = data[hdr+7] + top; + if( pc>0 ){ + u32 next, size; + if( pc<iCellFirst ){ + + + + return sqlite3CorruptError(1898); + } + while( 1 ){ + if( pc>iCellLast ){ + + return sqlite3CorruptError(1903); + } + next = ((&data[pc])[0]<<8 | (&data[pc])[1]); + size = ((&data[pc+2])[0]<<8 | (&data[pc+2])[1]); + nFree = nFree + size; + if( next<=pc+size+3 ) break; + pc = next; + } + if( next>0 ){ + + return sqlite3CorruptError(1913); + } + if( pc+size>(unsigned int)usableSize ){ + + return sqlite3CorruptError(1917); + } + } +# 1928 "src/btree.c" + if( nFree>usableSize || nFree<iCellFirst ){ + return sqlite3CorruptError(1929); + } + pPage->nFree = (u16)(nFree - iCellFirst); + return 0; +} + + + + + +static int btreeCellSizeCheck(MemPage *pPage){ + int iCellFirst; + int iCellLast; + int i; + int sz; + int pc; + u8 *data; + int usableSize; + int cellOffset; + + iCellFirst = pPage->cellOffset + 2*pPage->nCell; + usableSize = pPage->pBt->usableSize; + iCellLast = usableSize - 4; + data = pPage->aData; + cellOffset = pPage->cellOffset; + if( !pPage->leaf ) iCellLast--; + for(i=0; i<pPage->nCell; i++){ + pc = __builtin_bswap16(*(u16*)(&data[cellOffset+i*2])); + ; + ; + if( pc<iCellFirst || pc>iCellLast ){ + return sqlite3CorruptError(1960); + } + sz = pPage->xCellSize(pPage, &data[pc]); + ; + if( pc+sz>usableSize ){ + return sqlite3CorruptError(1965); + } + } + return 0; +} +# 1980 "src/btree.c" +static int btreeInitPage(MemPage *pPage){ + u8 *data; + BtShared *pBt; + + assert( pPage->pBt!=0 ); + assert( pPage->pBt->db!=0 ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); + assert( pPage->isInit==0 ); + + pBt = pPage->pBt; + data = pPage->aData + pPage->hdrOffset; + + + if( decodeFlags(pPage, data[0]) ){ + return sqlite3CorruptError(1997); + } + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nOverflow = 0; + pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; + pPage->aCellIdx = data + pPage->childPtrSize + 8; + pPage->aDataEnd = pPage->aData + pBt->usableSize; + pPage->aDataOfst = pPage->aData + pPage->childPtrSize; + + + pPage->nCell = ((&data[3])[0]<<8 | (&data[3])[1]); + if( pPage->nCell>((pBt->pageSize-8)/6) ){ + + return sqlite3CorruptError(2011); + } + ; + + + + + assert( pPage->nCell>0 + || (((((int)((&data[5])[0]<<8 | (&data[5])[1]))-1)&0xffff)+1)==(int)pBt->usableSize + || (sqlite3Config.neverCorrupt==0) ); + pPage->nFree = -1; + pPage->isInit = 1; + if( pBt->db->flags & 0x00200000 ){ + return btreeCellSizeCheck(pPage); + } + return 0; +} + + + + + +static void zeroPage(MemPage *pPage, int flags){ + unsigned char *data = pPage->aData; + BtShared *pBt = pPage->pBt; + u8 hdr = pPage->hdrOffset; + u16 first; + + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage) == data ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->btsFlags & 0x000c ){ + memset(&data[hdr], 0, pBt->usableSize - hdr); + } + data[hdr] = (char)flags; + first = hdr + ((flags&0x08)==0 ? 12 : 8); + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + ((&data[hdr+5])[0] = (u8)((pBt->usableSize)>>8), (&data[hdr+5])[1] = (u8)(pBt->usableSize)); + pPage->nFree = (u16)(pBt->usableSize - first); + decodeFlags(pPage, flags); + pPage->cellOffset = first; + pPage->aDataEnd = &data[pBt->usableSize]; + pPage->aCellIdx = &data[first]; + pPage->aDataOfst = &data[pPage->childPtrSize]; + pPage->nOverflow = 0; + assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); + pPage->maskPage = (u16)(pBt->pageSize - 1); + pPage->nCell = 0; + pPage->isInit = 1; +} + + + + + + +static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ + MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( pgno!=pPage->pgno ){ + pPage->aData = sqlite3PagerGetData(pDbPage); + pPage->pDbPage = pDbPage; + pPage->pBt = pBt; + pPage->pgno = pgno; + pPage->hdrOffset = pgno==1 ? 100 : 0; + } + assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); + return pPage; +} +# 2094 "src/btree.c" +static int btreeGetPage( + BtShared *pBt, + Pgno pgno, + MemPage **ppPage, + int flags +){ + int rc; + DbPage *pDbPage; + + assert( flags==0 || flags==0x01 || flags==0x02 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); + if( rc ) return rc; + *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); + return 0; +} + + + + + + +static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ + DbPage *pDbPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); + if( pDbPage ){ + return btreePageFromDbPage(pDbPage, pgno, pBt); + } + return 0; +} + + + + + +static Pgno btreePagecount(BtShared *pBt){ + return pBt->nPage; +} +u32 sqlite3BtreeLastPage(Btree *p){ + assert( sqlite3BtreeHoldsMutex(p) ); + assert( ((p->pBt->nPage)&0x80000000)==0 ); + return btreePagecount(p->pBt); +} +# 2152 "src/btree.c" +static int getAndInitPage( + BtShared *pBt, + Pgno pgno, + MemPage **ppPage, + BtCursor *pCur, + int bReadOnly +){ + int rc; + DbPage *pDbPage; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pCur==0 || ppPage==&pCur->pPage ); + assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); + assert( pCur==0 || pCur->iPage>0 ); + + if( pgno>btreePagecount(pBt) ){ + rc = sqlite3CorruptError(2167); + goto getAndInitPage_error1; + } + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); + if( rc ){ + goto getAndInitPage_error1; + } + *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( (*ppPage)->isInit==0 ){ + btreePageFromDbPage(pDbPage, pgno, pBt); + rc = btreeInitPage(*ppPage); + if( rc!=0 ){ + goto getAndInitPage_error2; + } + } + assert( (*ppPage)->pgno==pgno ); + assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); + + + + if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){ + rc = sqlite3CorruptError(2188); + goto getAndInitPage_error2; + } + return 0; + +getAndInitPage_error2: + releasePage(*ppPage); +getAndInitPage_error1: + if( pCur ){ + pCur->iPage--; + pCur->pPage = pCur->apPage[pCur->iPage]; + } + ; + assert( pgno!=0 || rc==11 ); + return rc; +} + + + + + + + +static void releasePageNotNull(MemPage *pPage){ + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefNotNull(pPage->pDbPage); +} +static void releasePage(MemPage *pPage){ + if( pPage ) releasePageNotNull(pPage); +} +static void releasePageOne(MemPage *pPage){ + assert( pPage!=0 ); + assert( pPage->aData ); + assert( pPage->pBt ); + assert( pPage->pDbPage!=0 ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefPageOne(pPage->pDbPage); +} +# 2243 "src/btree.c" +static int btreeGetUnusedPage( + BtShared *pBt, + Pgno pgno, + MemPage **ppPage, + int flags +){ + int rc = btreeGetPage(pBt, pgno, ppPage, flags); + if( rc==0 ){ + if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ + releasePage(*ppPage); + *ppPage = 0; + return sqlite3CorruptError(2254); + } + (*ppPage)->isInit = 0; + }else{ + *ppPage = 0; + } + return rc; +} +# 2272 "src/btree.c" +static void pageReinit(DbPage *pData){ + MemPage *pPage; + pPage = (MemPage *)sqlite3PagerGetExtra(pData); + assert( sqlite3PagerPageRefcount(pData)>0 ); + if( pPage->isInit ){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->isInit = 0; + if( sqlite3PagerPageRefcount(pData)>1 ){ + + + + + + + btreeInitPage(pPage); + } + } +} + + + + +static int btreeInvokeBusyHandler(void *pArg){ + BtShared *pBt = (BtShared*)pArg; + assert( pBt->db ); + assert( sqlite3_mutex_held(pBt->db->mutex) ); + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler, + sqlite3PagerFile(pBt->pPager)); +} +# 2323 "src/btree.c" +int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, + const char *zFilename, + sqlite3 *db, + Btree **ppBtree, + int flags, + int vfsFlags +){ + BtShared *pBt = 0; + Btree *p; + sqlite3_mutex *mutexOpen = 0; + int rc = 0; + u8 nReserve; + unsigned char zDbHeader[100]; + + + const int isTempDb = zFilename==0 || zFilename[0]==0; + + + + + + + + const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) + || (isTempDb && sqlite3TempInMemory(db)) + || (vfsFlags & 0x00000080)!=0; + + + assert( db!=0 ); + assert( pVfs!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( (flags&0xff)==flags ); + + + assert( (flags & 8)==0 || (flags & 4)!=0 ); + + + assert( (flags & 4)==0 || isTempDb ); + + if( isMemdb ){ + flags |= 2; + } + if( (vfsFlags & 0x00000100)!=0 && (isMemdb || isTempDb) ){ + vfsFlags = (vfsFlags & ~0x00000100) | 0x00000200; + } + p = sqlite3MallocZero(sizeof(Btree)); + if( !p ){ + return 7; + } + p->inTrans = 0; + p->db = db; + + p->lock.pBtree = p; + p->lock.iTable = 1; + + + + + + + + if( isTempDb==0 && (isMemdb==0 || (vfsFlags&0x00000040)!=0) ){ + if( vfsFlags & 0x00020000 ){ + int nFilename = sqlite3Strlen30(zFilename)+1; + int nFullPathname = pVfs->mxPathname+1; + char *zFullPathname = sqlite3Malloc(((nFullPathname)>(nFilename)?(nFullPathname):(nFilename))); + sqlite3_mutex *mutexShared; + + p->sharable = 1; + if( !zFullPathname ){ + sqlite3_free(p); + return 7; + } + if( isMemdb ){ + memcpy(zFullPathname, zFilename, nFilename); + }else{ + rc = sqlite3OsFullPathname(pVfs, zFilename, + nFullPathname, zFullPathname); + if( rc ){ + sqlite3_free(zFullPathname); + sqlite3_free(p); + return rc; + } + } + + mutexOpen = sqlite3MutexAlloc(4); + sqlite3_mutex_enter(mutexOpen); + mutexShared = sqlite3MutexAlloc(2); + sqlite3_mutex_enter(mutexShared); + + for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){ + assert( pBt->nRef>0 ); + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) + && sqlite3PagerVfs(pBt->pPager)==pVfs ){ + int iDb; + for(iDb=db->nDb-1; iDb>=0; iDb--){ + Btree *pExisting = db->aDb[iDb].pBt; + if( pExisting && pExisting->pBt==pBt ){ + sqlite3_mutex_leave(mutexShared); + sqlite3_mutex_leave(mutexOpen); + sqlite3_free(zFullPathname); + sqlite3_free(p); + return 19; + } + } + p->pBt = pBt; + pBt->nRef++; + break; + } + } + sqlite3_mutex_leave(mutexShared); + sqlite3_free(zFullPathname); + } +# 2447 "src/btree.c" + } + + if( pBt==0 ){ + + + + + + assert( sizeof(i64)==8 ); + assert( sizeof(u64)==8 ); + assert( sizeof(u32)==4 ); + assert( sizeof(u16)==2 ); + assert( sizeof(Pgno)==4 ); + + pBt = sqlite3MallocZero( sizeof(*pBt) ); + if( pBt==0 ){ + rc = 7; + goto btree_open_out; + } + rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, + sizeof(MemPage), flags, vfsFlags, pageReinit); + if( rc==0 ){ + sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); + rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); + } + if( rc!=0 ){ + goto btree_open_out; + } + pBt->openFlags = (u8)flags; + pBt->db = db; + sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); + p->pBt = pBt; + + pBt->pCursor = 0; + pBt->pPage1 = 0; + if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= 0x0001; +# 2491 "src/btree.c" + pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); + if( pBt->pageSize<512 || pBt->pageSize>65536 + || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ + pBt->pageSize = 0; + + + + + + + + if( zFilename && !isMemdb ){ + pBt->autoVacuum = (0 ? 1 : 0); + pBt->incrVacuum = (0==2 ? 1 : 0); + } + + nReserve = 0; + }else{ + + + + nReserve = zDbHeader[20]; + pBt->btsFlags |= 0x0002; + + pBt->autoVacuum = (sqlite3Get4byte(&zDbHeader[36 + 4*4])?1:0); + pBt->incrVacuum = (sqlite3Get4byte(&zDbHeader[36 + 7*4])?1:0); + + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + if( rc ) goto btree_open_out; + pBt->usableSize = pBt->pageSize - nReserve; + assert( (pBt->pageSize & 7)==0 ); + + + + + pBt->nRef = 1; + if( p->sharable ){ + sqlite3_mutex *mutexShared; + mutexShared = sqlite3MutexAlloc(2); + if( 1 && sqlite3Config.bCoreMutex ){ + pBt->mutex = sqlite3MutexAlloc(0); + if( pBt->mutex==0 ){ + rc = 7; + goto btree_open_out; + } + } + sqlite3_mutex_enter(mutexShared); + pBt->pNext = sqlite3SharedCacheList; + sqlite3SharedCacheList = pBt; + sqlite3_mutex_leave(mutexShared); + } + + } + + + + + + + if( p->sharable ){ + int i; + Btree *pSib; + for(i=0; i<db->nDb; i++){ + if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){ + while( pSib->pPrev ){ pSib = pSib->pPrev; } + if( (uptr)p->pBt<(uptr)pSib->pBt ){ + p->pNext = pSib; + p->pPrev = 0; + pSib->pPrev = p; + }else{ + while( pSib->pNext && (uptr)pSib->pNext->pBt<(uptr)p->pBt ){ + pSib = pSib->pNext; + } + p->pNext = pSib->pNext; + p->pPrev = pSib; + if( p->pNext ){ + p->pNext->pPrev = p; + } + pSib->pNext = p; + } + break; + } + } + } + + *ppBtree = p; + +btree_open_out: + if( rc!=0 ){ + if( pBt && pBt->pPager ){ + sqlite3PagerClose(pBt->pPager, 0); + } + sqlite3_free(pBt); + sqlite3_free(p); + *ppBtree = 0; + }else{ + sqlite3_file *pFile; + + + + + + if( sqlite3BtreeSchema(p, 0, 0)==0 ){ + sqlite3PagerSetCachesize(p->pBt->pPager, -2000); + } + + pFile = sqlite3PagerFile(pBt->pPager); + if( pFile->pMethods ){ + sqlite3OsFileControlHint(pFile, 30, (void*)&pBt->db); + } + } + if( mutexOpen ){ + assert( sqlite3_mutex_held(mutexOpen) ); + sqlite3_mutex_leave(mutexOpen); + } + assert( rc!=0 || sqlite3BtreeConnectionCount(*ppBtree)>0 ); + return rc; +} + + + + + + + +static int removeFromSharingList(BtShared *pBt){ + + sqlite3_mutex *pMaster; + BtShared *pList; + int removed = 0; + + assert( sqlite3_mutex_notheld(pBt->mutex) ); + pMaster = sqlite3MutexAlloc(2); + sqlite3_mutex_enter(pMaster); + pBt->nRef--; + if( pBt->nRef<=0 ){ + if( sqlite3SharedCacheList==pBt ){ + sqlite3SharedCacheList = pBt->pNext; + }else{ + pList = sqlite3SharedCacheList; + while( (pList) && pList->pNext!=pBt ){ + pList=pList->pNext; + } + if( (pList) ){ + pList->pNext = pBt->pNext; + } + } + if( 1 ){ + sqlite3_mutex_free(pBt->mutex); + } + removed = 1; + } + sqlite3_mutex_leave(pMaster); + return removed; + + + +} + + + + + + +static void allocateTempSpace(BtShared *pBt){ + if( !pBt->pTmpSpace ){ + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); +# 2675 "src/btree.c" + if( pBt->pTmpSpace ){ + memset(pBt->pTmpSpace, 0, 8); + pBt->pTmpSpace += 4; + } + } +} + + + + +static void freeTempSpace(BtShared *pBt){ + if( pBt->pTmpSpace ){ + pBt->pTmpSpace -= 4; + sqlite3PageFree(pBt->pTmpSpace); + pBt->pTmpSpace = 0; + } +} + + + + +int sqlite3BtreeClose(Btree *p){ + BtShared *pBt = p->pBt; + BtCursor *pCur; + + + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + pCur = pBt->pCursor; + while( pCur ){ + BtCursor *pTmp = pCur; + pCur = pCur->pNext; + if( pTmp->pBtree==p ){ + sqlite3BtreeCloseCursor(pTmp); + } + } + + + + + + sqlite3BtreeRollback(p, 0, 0); + sqlite3BtreeLeave(p); + + + + + + assert( p->wantToLock==0 && p->locked==0 ); + if( !p->sharable || removeFromSharingList(pBt) ){ + + + + + + assert( !pBt->pCursor ); + sqlite3PagerClose(pBt->pPager, p->db); + if( pBt->xFreeSchema && pBt->pSchema ){ + pBt->xFreeSchema(pBt->pSchema); + } + sqlite3DbFree(0, pBt->pSchema); + freeTempSpace(pBt); + sqlite3_free(pBt); + } + + + assert( p->wantToLock==0 ); + assert( p->locked==0 ); + if( p->pPrev ) p->pPrev->pNext = p->pNext; + if( p->pNext ) p->pNext->pPrev = p->pPrev; + + + sqlite3_free(p); + return 0; +} +# 2758 "src/btree.c" +int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetCachesize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return 0; +} +# 2777 "src/btree.c" +int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){ + BtShared *pBt = p->pBt; + int res; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return res; +} + + + + + + +int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); + sqlite3BtreeLeave(p); + return 0; +} +# 2811 "src/btree.c" +int sqlite3BtreeSetPagerFlags( + Btree *p, + unsigned pgFlags +){ + BtShared *pBt = p->pBt; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetFlags(pBt->pPager, pgFlags); + sqlite3BtreeLeave(p); + return 0; +} +# 2844 "src/btree.c" +int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ + int rc = 0; + BtShared *pBt = p->pBt; + assert( nReserve>=-1 && nReserve<=255 ); + sqlite3BtreeEnter(p); + + + + if( pBt->btsFlags & 0x0002 ){ + sqlite3BtreeLeave(p); + return 8; + } + if( nReserve<0 ){ + nReserve = pBt->pageSize - pBt->usableSize; + } + assert( nReserve>=0 && nReserve<=255 ); + if( pageSize>=512 && pageSize<=65536 && + ((pageSize-1)&pageSize)==0 ){ + assert( (pageSize & 7)==0 ); + assert( !pBt->pCursor ); + pBt->pageSize = (u32)pageSize; + freeTempSpace(pBt); + } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + pBt->usableSize = pBt->pageSize - (u16)nReserve; + if( iFix ) pBt->btsFlags |= 0x0002; + sqlite3BtreeLeave(p); + return rc; +} + + + + +int sqlite3BtreeGetPageSize(Btree *p){ + return p->pBt->pageSize; +} +# 2892 "src/btree.c" +int sqlite3BtreeGetReserveNoMutex(Btree *p){ + int n; + assert( sqlite3_mutex_held(p->pBt->mutex) ); + n = p->pBt->pageSize - p->pBt->usableSize; + return n; +} +# 2908 "src/btree.c" +int sqlite3BtreeGetOptimalReserve(Btree *p){ + int n; + sqlite3BtreeEnter(p); + n = sqlite3BtreeGetReserveNoMutex(p); + + + + sqlite3BtreeLeave(p); + return n; +} + + + + + + + +int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ + int n; + sqlite3BtreeEnter(p); + n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); + sqlite3BtreeLeave(p); + return n; +} +# 2951 "src/btree.c" +int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ + int b; + if( p==0 ) return 0; + sqlite3BtreeEnter(p); + assert( 0x0008==0x0004*2 ); + assert( 0x000c==(0x0008|0x0004) ); + if( newFlag>=0 ){ + p->pBt->btsFlags &= ~0x000c; + p->pBt->btsFlags |= 0x0004*newFlag; + } + b = (p->pBt->btsFlags & 0x000c)/0x0004; + sqlite3BtreeLeave(p); + return b; +} + + + + + + + +int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ + + + + BtShared *pBt = p->pBt; + int rc = 0; + u8 av = (u8)autoVacuum; + + sqlite3BtreeEnter(p); + if( (pBt->btsFlags & 0x0002)!=0 && (av ?1:0)!=pBt->autoVacuum ){ + rc = 8; + }else{ + pBt->autoVacuum = av ?1:0; + pBt->incrVacuum = av==2 ?1:0; + } + sqlite3BtreeLeave(p); + return rc; + +} + + + + + +int sqlite3BtreeGetAutoVacuum(Btree *p){ + + + + int rc; + sqlite3BtreeEnter(p); + rc = ( + (!p->pBt->autoVacuum)?0: + (!p->pBt->incrVacuum)?1: + 2 + ); + sqlite3BtreeLeave(p); + return rc; + +} +# 3040 "src/btree.c" +static int newDatabase(BtShared*); +# 3052 "src/btree.c" +static int lockBtree(BtShared *pBt){ + int rc; + MemPage *pPage1; + u32 nPage; + u32 nPageFile = 0; + u32 nPageHeader; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pBt->pPage1==0 ); + rc = sqlite3PagerSharedLock(pBt->pPager); + if( rc!=0 ) return rc; + rc = btreeGetPage(pBt, 1, &pPage1, 0); + if( rc!=0 ) return rc; + + + + + nPage = nPageHeader = sqlite3Get4byte(28+(u8*)pPage1->aData); + sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); + if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ + nPage = nPageFile; + } + if( (pBt->db->flags & 0x02000000)!=0 ){ + nPage = 0; + } + if( nPage>0 ){ + u32 pageSize; + u32 usableSize; + u8 *page1 = pPage1->aData; + rc = 26; + + + + if( memcmp(page1, zMagicHeader, 16)!=0 ){ + goto page1_init_failed; + } +# 3097 "src/btree.c" + if( page1[18]>2 ){ + pBt->btsFlags |= 0x0001; + } + if( page1[19]>2 ){ + goto page1_init_failed; + } +# 3112 "src/btree.c" + if( page1[19]==2 && (pBt->btsFlags & 0x0020)==0 ){ + int isOpen = 0; + rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); + if( rc!=0 ){ + goto page1_init_failed; + }else{ + ; + if( isOpen==0 ){ + releasePageOne(pPage1); + return 0; + } + } + rc = 26; + }else{ + ; + } +# 3136 "src/btree.c" + if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ + goto page1_init_failed; + } + + + + pageSize = (page1[16]<<8) | (page1[17]<<16); + + + if( ((pageSize-1)&pageSize)!=0 + || pageSize>65536 + || pageSize<=256 + ){ + goto page1_init_failed; + } + pBt->btsFlags |= 0x0002; + assert( (pageSize & 7)==0 ); + + + + + + + + usableSize = pageSize - page1[20]; + if( (u32)pageSize!=pBt->pageSize ){ + + + + + + + releasePageOne(pPage1); + pBt->usableSize = usableSize; + pBt->pageSize = pageSize; + freeTempSpace(pBt); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + pageSize-usableSize); + return rc; + } + if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){ + rc = sqlite3CorruptError(3177); + goto page1_init_failed; + } + + + + if( usableSize<480 ){ + goto page1_init_failed; + } + pBt->pageSize = pageSize; + pBt->usableSize = usableSize; + + pBt->autoVacuum = (sqlite3Get4byte(&page1[36 + 4*4])?1:0); + pBt->incrVacuum = (sqlite3Get4byte(&page1[36 + 7*4])?1:0); + + } +# 3207 "src/btree.c" + pBt->maxLocal = (u16)((pBt->usableSize-12)*64/255 - 23); + pBt->minLocal = (u16)((pBt->usableSize-12)*32/255 - 23); + pBt->maxLeaf = (u16)(pBt->usableSize - 35); + pBt->minLeaf = (u16)((pBt->usableSize-12)*32/255 - 23); + if( pBt->maxLocal>127 ){ + pBt->max1bytePayload = 127; + }else{ + pBt->max1bytePayload = (u8)pBt->maxLocal; + } + assert( pBt->maxLeaf + 23 <= ((int)(pBt->pageSize-8)) ); + pBt->pPage1 = pPage1; + pBt->nPage = nPage; + return 0; + +page1_init_failed: + releasePageOne(pPage1); + pBt->pPage1 = 0; + return rc; +} +# 3259 "src/btree.c" +static void unlockBtreeIfUnused(BtShared *pBt){ + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>0 ); + if( pBt->inTransaction==0 && pBt->pPage1!=0 ){ + MemPage *pPage1 = pBt->pPage1; + assert( pPage1->aData ); + assert( sqlite3PagerRefcount(pBt->pPager)==1 ); + pBt->pPage1 = 0; + releasePageOne(pPage1); + } +} + + + + + + +static int newDatabase(BtShared *pBt){ + MemPage *pP1; + unsigned char *data; + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pBt->nPage>0 ){ + return 0; + } + pP1 = pBt->pPage1; + assert( pP1!=0 ); + data = pP1->aData; + rc = sqlite3PagerWrite(pP1->pDbPage); + if( rc ) return rc; + memcpy(data, zMagicHeader, sizeof(zMagicHeader)); + assert( sizeof(zMagicHeader)==16 ); + data[16] = (u8)((pBt->pageSize>>8)&0xff); + data[17] = (u8)((pBt->pageSize>>16)&0xff); + data[18] = 1; + data[19] = 1; + assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize); + data[20] = (u8)(pBt->pageSize - pBt->usableSize); + data[21] = 64; + data[22] = 32; + data[23] = 32; + memset(&data[24], 0, 100-24); + zeroPage(pP1, 0x01|0x08|0x04 ); + pBt->btsFlags |= 0x0002; + + assert( pBt->autoVacuum==1 || pBt->autoVacuum==0 ); + assert( pBt->incrVacuum==1 || pBt->incrVacuum==0 ); + sqlite3Put4byte(&data[36 + 4*4], pBt->autoVacuum); + sqlite3Put4byte(&data[36 + 7*4], pBt->incrVacuum); + + pBt->nPage = 1; + data[31] = 1; + return 0; +} + + + + + + +int sqlite3BtreeNewDb(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + p->pBt->nPage = 0; + rc = newDatabase(p->pBt); + sqlite3BtreeLeave(p); + return rc; +} +# 3364 "src/btree.c" +int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ + BtShared *pBt = p->pBt; + int rc = 0; + + sqlite3BtreeEnter(p); + assert( p->pBt->inTransaction!=0 || p->pBt->nTransaction==0 ); assert( p->pBt->inTransaction>=p->inTrans );; + + + + + + if( p->inTrans==2 || (p->inTrans==1 && !wrflag) ){ + goto trans_begun; + } + assert( pBt->inTransaction==2 || (pBt->bDoTruncate)==0 ); + + if( (p->db->flags & 0x02000000) + && sqlite3PagerIsreadonly(pBt->pPager)==0 + ){ + pBt->btsFlags &= ~0x0001; + } + + + if( (pBt->btsFlags & 0x0001)!=0 && wrflag ){ + rc = 8; + goto trans_begun; + } + + + { + sqlite3 *pBlock = 0; + + + + + if( (wrflag && pBt->inTransaction==2) + || (pBt->btsFlags & 0x0080)!=0 + ){ + pBlock = pBt->pWriter->db; + }else if( wrflag>1 ){ + BtLock *pIter; + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + if( pIter->pBtree!=p ){ + pBlock = pIter->pBtree->db; + break; + } + } + } + if( pBlock ){ + ; + rc = (6 | (1<<8)); + goto trans_begun; + } + } + + + + + + rc = querySharedCacheTableLock(p, 1, 1); + if( 0!=rc ) goto trans_begun; + + pBt->btsFlags &= ~0x0010; + if( pBt->nPage==0 ) pBt->btsFlags |= 0x0010; + do { + + + + + + + + while( pBt->pPage1==0 && 0==(rc = lockBtree(pBt)) ); + + if( rc==0 && wrflag ){ + if( (pBt->btsFlags & 0x0001)!=0 ){ + rc = 8; + }else{ + rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); + if( rc==0 ){ + rc = newDatabase(pBt); + }else if( rc==(5 | (2<<8)) && pBt->inTransaction==0 ){ + + + + rc = 5; + } + } + } + + if( rc!=0 ){ + unlockBtreeIfUnused(pBt); + } + }while( (rc&0xFF)==5 && pBt->inTransaction==0 && + btreeInvokeBusyHandler(pBt) ); + ; + + if( rc==0 ){ + if( p->inTrans==0 ){ + pBt->nTransaction++; + + if( p->sharable ){ + assert( p->lock.pBtree==p && p->lock.iTable==1 ); + p->lock.eLock = 1; + p->lock.pNext = pBt->pLock; + pBt->pLock = &p->lock; + } + + } + p->inTrans = (wrflag?2:1); + if( p->inTrans>pBt->inTransaction ){ + pBt->inTransaction = p->inTrans; + } + if( wrflag ){ + MemPage *pPage1 = pBt->pPage1; + + assert( !pBt->pWriter ); + pBt->pWriter = p; + pBt->btsFlags &= ~0x0040; + if( wrflag>1 ) pBt->btsFlags |= 0x0040; +# 3492 "src/btree.c" + if( pBt->nPage!=sqlite3Get4byte(&pPage1->aData[28]) ){ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc==0 ){ + sqlite3Put4byte(&pPage1->aData[28], pBt->nPage); + } + } + } + } + +trans_begun: + if( rc==0 ){ + if( pSchemaVersion ){ + *pSchemaVersion = sqlite3Get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + + + + + rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + } + } + + assert( p->pBt->inTransaction!=0 || p->pBt->nTransaction==0 ); assert( p->pBt->inTransaction>=p->inTrans );; + sqlite3BtreeLeave(p); + return rc; +} +# 3527 "src/btree.c" +static int setChildPtrmaps(MemPage *pPage){ + int i; + int nCell; + int rc; + BtShared *pBt = pPage->pBt; + Pgno pgno = pPage->pgno; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + rc = pPage->isInit ? 0 : btreeInitPage(pPage); + if( rc!=0 ) return rc; + nCell = pPage->nCell; + + for(i=0; i<nCell; i++){ + u8 *pCell = ((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(i)])))); + + ptrmapPutOvflPtr(pPage, pPage, pCell, &rc); + + if( !pPage->leaf ){ + Pgno childPgno = sqlite3Get4byte(pCell); + ptrmapPut(pBt, childPgno, 5, pgno, &rc); + } + } + + if( !pPage->leaf ){ + Pgno childPgno = sqlite3Get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapPut(pBt, childPgno, 5, pgno, &rc); + } + + return rc; +} +# 3572 "src/btree.c" +static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + if( eType==4 ){ + + if( sqlite3Get4byte(pPage->aData)!=iFrom ){ + return sqlite3CorruptError(3578); + } + sqlite3Put4byte(pPage->aData, iTo); + }else{ + int i; + int nCell; + int rc; + + rc = pPage->isInit ? 0 : btreeInitPage(pPage); + if( rc ) return rc; + nCell = pPage->nCell; + + for(i=0; i<nCell; i++){ + u8 *pCell = ((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(i)])))); + if( eType==3 ){ + CellInfo info; + pPage->xParseCell(pPage, pCell, &info); + if( info.nLocal<info.nPayload ){ + if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){ + return sqlite3CorruptError(3597); + } + if( iFrom==sqlite3Get4byte(pCell+info.nSize-4) ){ + sqlite3Put4byte(pCell+info.nSize-4, iTo); + break; + } + } + }else{ + if( sqlite3Get4byte(pCell)==iFrom ){ + sqlite3Put4byte(pCell, iTo); + break; + } + } + } + + if( i==nCell ){ + if( eType!=5 || + sqlite3Get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ + return sqlite3CorruptError(3615); + } + sqlite3Put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); + } + } + return 0; +} +# 3633 "src/btree.c" +static int relocatePage( + BtShared *pBt, + MemPage *pDbPage, + u8 eType, + Pgno iPtrPage, + Pgno iFreePage, + int isCommit +){ + MemPage *pPtrPage; + Pgno iDbPage = pDbPage->pgno; + Pager *pPager = pBt->pPager; + int rc; + + assert( eType==4 || eType==3 || + eType==5 || eType==1 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( pDbPage->pBt==pBt ); + if( iDbPage<3 ) return sqlite3CorruptError(3650); + + + + ; + rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); + if( rc!=0 ){ + return rc; + } + pDbPage->pgno = iFreePage; +# 3669 "src/btree.c" + if( eType==5 || eType==1 ){ + rc = setChildPtrmaps(pDbPage); + if( rc!=0 ){ + return rc; + } + }else{ + Pgno nextOvfl = sqlite3Get4byte(pDbPage->aData); + if( nextOvfl!=0 ){ + ptrmapPut(pBt, nextOvfl, 4, iFreePage, &rc); + if( rc!=0 ){ + return rc; + } + } + } + + + + + + if( eType!=1 ){ + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); + if( rc!=0 ){ + return rc; + } + rc = sqlite3PagerWrite(pPtrPage->pDbPage); + if( rc!=0 ){ + releasePage(pPtrPage); + return rc; + } + rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); + releasePage(pPtrPage); + if( rc==0 ){ + ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc); + } + } + return rc; +} + + +static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); +# 3727 "src/btree.c" +static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ + Pgno nFreeList; + int rc; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( iLastPg>nFin ); + + if( !(ptrmapPageno((pBt), (iLastPg))==(iLastPg)) && iLastPg!=((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ + u8 eType; + Pgno iPtrPage; + + nFreeList = sqlite3Get4byte(&pBt->pPage1->aData[36]); + if( nFreeList==0 ){ + return 101; + } + + rc = ptrmapGet(pBt, iLastPg, &eType, &iPtrPage); + if( rc!=0 ){ + return rc; + } + if( eType==1 ){ + return sqlite3CorruptError(3748); + } + + if( eType==2 ){ + if( bCommit==0 ){ + + + + + + Pgno iFreePg; + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iLastPg, 1); + if( rc!=0 ){ + return rc; + } + assert( iFreePg==iLastPg ); + releasePage(pFreePg); + } + } else { + Pgno iFreePg; + MemPage *pLastPg; + u8 eMode = 0; + Pgno iNear = 0; + + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); + if( rc!=0 ){ + return rc; + } +# 3785 "src/btree.c" + if( bCommit==0 ){ + eMode = 2; + iNear = nFin; + } + do { + MemPage *pFreePg; + rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode); + if( rc!=0 ){ + releasePage(pLastPg); + return rc; + } + releasePage(pFreePg); + }while( bCommit && iFreePg>nFin ); + assert( iFreePg<iLastPg ); + + rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, bCommit); + releasePage(pLastPg); + if( rc!=0 ){ + return rc; + } + } + } + + if( bCommit==0 ){ + do { + iLastPg--; + }while( iLastPg==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) || (ptrmapPageno((pBt), (iLastPg))==(iLastPg)) ); + pBt->bDoTruncate = 1; + pBt->nPage = iLastPg; + } + return 0; +} + + + + + + +static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){ + int nEntry; + Pgno nPtrmap; + Pgno nFin; + + nEntry = pBt->usableSize/5; + nPtrmap = (nFree-nOrig+ptrmapPageno(pBt, nOrig)+nEntry)/nEntry; + nFin = nOrig - nFree - nPtrmap; + if( nOrig>((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) && nFin<((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ + nFin--; + } + while( (ptrmapPageno((pBt), (nFin))==(nFin)) || nFin==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ + nFin--; + } + + return nFin; +} +# 3849 "src/btree.c" +int sqlite3BtreeIncrVacuum(Btree *p){ + int rc; + BtShared *pBt = p->pBt; + + sqlite3BtreeEnter(p); + assert( pBt->inTransaction==2 && p->inTrans==2 ); + if( !pBt->autoVacuum ){ + rc = 101; + }else{ + Pgno nOrig = btreePagecount(pBt); + Pgno nFree = sqlite3Get4byte(&pBt->pPage1->aData[36]); + Pgno nFin = finalDbSize(pBt, nOrig, nFree); + + if( nOrig<nFin ){ + rc = sqlite3CorruptError(3863); + }else if( nFree>0 ){ + rc = saveAllCursors(pBt, 0, 0); + if( rc==0 ){ + invalidateAllOverflowCache(pBt); + rc = incrVacuumStep(pBt, nFin, nOrig, 0); + } + if( rc==0 ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + sqlite3Put4byte(&pBt->pPage1->aData[28], pBt->nPage); + } + }else{ + rc = 101; + } + } + sqlite3BtreeLeave(p); + return rc; +} +# 3891 "src/btree.c" +static int autoVacuumCommit(BtShared *pBt){ + int rc = 0; + Pager *pPager = pBt->pPager; + + + assert( sqlite3_mutex_held(pBt->mutex) ); + invalidateAllOverflowCache(pBt); + assert(pBt->autoVacuum); + if( !pBt->incrVacuum ){ + Pgno nFin; + Pgno nFree; + Pgno iFree; + Pgno nOrig; + + nOrig = btreePagecount(pBt); + if( (ptrmapPageno((pBt), (nOrig))==(nOrig)) || nOrig==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ + + + + + return sqlite3CorruptError(3911); + } + + nFree = sqlite3Get4byte(&pBt->pPage1->aData[36]); + nFin = finalDbSize(pBt, nOrig, nFree); + if( nFin>nOrig ) return sqlite3CorruptError(3916); + if( nFin<nOrig ){ + rc = saveAllCursors(pBt, 0, 0); + } + for(iFree=nOrig; iFree>nFin && rc==0; iFree--){ + rc = incrVacuumStep(pBt, nFin, iFree, 1); + } + if( (rc==101 || rc==0) && nFree>0 ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + sqlite3Put4byte(&pBt->pPage1->aData[32], 0); + sqlite3Put4byte(&pBt->pPage1->aData[36], 0); + sqlite3Put4byte(&pBt->pPage1->aData[28], nFin); + pBt->bDoTruncate = 1; + pBt->nPage = nFin; + } + if( rc!=0 ){ + sqlite3PagerRollback(pPager); + } + } + + assert( nRef>=sqlite3PagerRefcount(pPager) ); + return rc; +} +# 3970 "src/btree.c" +int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ + int rc = 0; + if( p->inTrans==2 ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + + if( pBt->autoVacuum ){ + rc = autoVacuumCommit(pBt); + if( rc!=0 ){ + sqlite3BtreeLeave(p); + return rc; + } + } + if( pBt->bDoTruncate ){ + sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); + } + + rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0); + sqlite3BtreeLeave(p); + } + return rc; +} + + + + + +static void btreeEndTransaction(Btree *p){ + BtShared *pBt = p->pBt; + sqlite3 *db = p->db; + assert( sqlite3BtreeHoldsMutex(p) ); + + + pBt->bDoTruncate = 0; + + if( p->inTrans>0 && db->nVdbeRead>1 ){ + + + + downgradeAllSharedCacheTableLocks(p); + p->inTrans = 1; + }else{ + + + + + if( p->inTrans!=0 ){ + clearAllSharedCacheTableLocks(p); + pBt->nTransaction--; + if( 0==pBt->nTransaction ){ + pBt->inTransaction = 0; + } + } + + + + p->inTrans = 0; + unlockBtreeIfUnused(pBt); + } + + assert( p->pBt->inTransaction!=0 || p->pBt->nTransaction==0 ); assert( p->pBt->inTransaction>=p->inTrans );; +} +# 4059 "src/btree.c" +int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ + + if( p->inTrans==0 ) return 0; + sqlite3BtreeEnter(p); + assert( p->pBt->inTransaction!=0 || p->pBt->nTransaction==0 ); assert( p->pBt->inTransaction>=p->inTrans );; + + + + + if( p->inTrans==2 ){ + int rc; + BtShared *pBt = p->pBt; + assert( pBt->inTransaction==2 ); + assert( pBt->nTransaction>0 ); + rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); + if( rc!=0 && bCleanup==0 ){ + sqlite3BtreeLeave(p); + return rc; + } + p->iDataVersion--; + pBt->inTransaction = 1; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return 0; +} + + + + +int sqlite3BtreeCommit(Btree *p){ + int rc; + sqlite3BtreeEnter(p); + rc = sqlite3BtreeCommitPhaseOne(p, 0); + if( rc==0 ){ + rc = sqlite3BtreeCommitPhaseTwo(p, 0); + } + sqlite3BtreeLeave(p); + return rc; +} +# 4128 "src/btree.c" +int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ + BtCursor *p; + int rc = 0; + + assert( (writeOnly==0 || writeOnly==1) && 0x01==1 ); + if( pBtree ){ + sqlite3BtreeEnter(pBtree); + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( writeOnly && (p->curFlags & 0x01)==0 ){ + if( p->eState==0 || p->eState==2 ){ + rc = saveCursorPosition(p); + if( rc!=0 ){ + (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0); + break; + } + } + }else{ + sqlite3BtreeClearCursor(p); + p->eState = 4; + p->skipNext = errCode; + } + btreeReleaseAllCursorPages(p); + } + sqlite3BtreeLeave(pBtree); + } + return rc; +} + + + + + +static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ + int nPage = sqlite3Get4byte(&pPage1->aData[28]); + ; + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); + ; + pBt->nPage = nPage; +} +# 4179 "src/btree.c" +int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ + int rc; + BtShared *pBt = p->pBt; + MemPage *pPage1; + + assert( writeOnly==1 || writeOnly==0 ); + assert( tripCode==(4 | (2<<8)) || tripCode==0 ); + sqlite3BtreeEnter(p); + if( tripCode==0 ){ + rc = tripCode = saveAllCursors(pBt, 0, 0); + if( rc ) writeOnly = 0; + }else{ + rc = 0; + } + if( tripCode ){ + int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly); + assert( rc==0 || (writeOnly==0 && rc2==0) ); + if( rc2!=0 ) rc = rc2; + } + assert( p->pBt->inTransaction!=0 || p->pBt->nTransaction==0 ); assert( p->pBt->inTransaction>=p->inTrans );; + + if( p->inTrans==2 ){ + int rc2; + + assert( 2==pBt->inTransaction ); + rc2 = sqlite3PagerRollback(pBt->pPager); + if( rc2!=0 ){ + rc = rc2; + } + + + + + if( btreeGetPage(pBt, 1, &pPage1, 0)==0 ){ + btreeSetNPage(pBt, pPage1); + releasePageOne(pPage1); + } + assert( countValidCursors(pBt, 1)==0 ); + pBt->inTransaction = 1; + btreeClearHasContent(pBt); + } + + btreeEndTransaction(p); + sqlite3BtreeLeave(p); + return rc; +} +# 4244 "src/btree.c" +int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==2 ); + assert( (pBt->btsFlags & 0x0001)==0 ); + assert( iStatement>0 ); + assert( iStatement>p->db->nSavepoint ); + assert( pBt->inTransaction==2 ); + + + + + + rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); + sqlite3BtreeLeave(p); + return rc; +} +# 4275 "src/btree.c" +int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ + int rc = 0; + if( p && p->inTrans==2 ){ + BtShared *pBt = p->pBt; + assert( op==1 || op==2 ); + assert( iSavepoint>=0 || (iSavepoint==-1 && op==2) ); + sqlite3BtreeEnter(p); + if( op==2 ){ + rc = saveAllCursors(pBt, 0, 0); + } + if( rc==0 ){ + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + } + if( rc==0 ){ + if( iSavepoint<0 && (pBt->btsFlags & 0x0010)!=0 ){ + pBt->nPage = 0; + } + rc = newDatabase(pBt); + btreeSetNPage(pBt, pBt->pPage1); + + + + assert( (sqlite3Config.neverCorrupt==0) || pBt->nPage>0 ); + } + sqlite3BtreeLeave(p); + } + return rc; +} +# 4346 "src/btree.c" +static int btreeCursor( + Btree *p, + int iTable, + int wrFlag, + struct KeyInfo *pKeyInfo, + BtCursor *pCur +){ + BtShared *pBt = p->pBt; + BtCursor *pX; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( wrFlag==0 + || wrFlag==0x00000004 + || wrFlag==(0x00000004|0x00000008) + ); + + + + + + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) ); + assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); + + + assert( p->inTrans>0 ); + assert( wrFlag==0 || p->inTrans==2 ); + assert( pBt->pPage1 && pBt->pPage1->aData ); + assert( wrFlag==0 || (pBt->btsFlags & 0x0001)==0 ); + + if( wrFlag ){ + allocateTempSpace(pBt); + if( pBt->pTmpSpace==0 ) return 7; + } + if( iTable==1 && btreePagecount(pBt)==0 ){ + assert( wrFlag==0 ); + iTable = 0; + } + + + + pCur->pgnoRoot = (Pgno)iTable; + pCur->iPage = -1; + pCur->pKeyInfo = pKeyInfo; + pCur->pBtree = p; + pCur->pBt = pBt; + pCur->curFlags = wrFlag ? 0x01 : 0; + pCur->curPagerFlags = wrFlag ? 0 : 0x02; + + + for(pX=pBt->pCursor; pX; pX=pX->pNext){ + if( pX->pgnoRoot==(Pgno)iTable ){ + pX->curFlags |= 0x20; + pCur->curFlags |= 0x20; + } + } + pCur->pNext = pBt->pCursor; + pBt->pCursor = pCur; + pCur->eState = 1; + return 0; +} +int sqlite3BtreeCursor( + Btree *p, + int iTable, + int wrFlag, + struct KeyInfo *pKeyInfo, + BtCursor *pCur +){ + int rc; + if( iTable<1 ){ + rc = sqlite3CorruptError(4415); + }else{ + sqlite3BtreeEnter(p); + rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); + sqlite3BtreeLeave(p); + } + return rc; +} +# 4432 "src/btree.c" +int sqlite3BtreeCursorSize(void){ + return (((sizeof(BtCursor))+7)&~7); +} +# 4444 "src/btree.c" +void sqlite3BtreeCursorZero(BtCursor *p){ + memset(p, 0, ((int)((char*)&((BtCursor*)0)->pBt))); +} + + + + + +int sqlite3BtreeCloseCursor(BtCursor *pCur){ + Btree *pBtree = pCur->pBtree; + if( pBtree ){ + BtShared *pBt = pCur->pBt; + sqlite3BtreeEnter(pBtree); + assert( pBt->pCursor!=0 ); + if( pBt->pCursor==pCur ){ + pBt->pCursor = pCur->pNext; + }else{ + BtCursor *pPrev = pBt->pCursor; + do{ + if( pPrev->pNext==pCur ){ + pPrev->pNext = pCur->pNext; + break; + } + pPrev = pPrev->pNext; + }while( (pPrev) ); + } + btreeReleaseAllCursorPages(pCur); + unlockBtreeIfUnused(pBt); + sqlite3_free(pCur->aOverflow); + sqlite3_free(pCur->pKey); + sqlite3BtreeLeave(pBtree); + pCur->pBtree = 0; + } + return 0; +} +# 4506 "src/btree.c" +static void getCellInfo(BtCursor *pCur){ + if( pCur->info.nSize==0 ){ + pCur->curFlags |= 0x02; + btreeParseCell(pCur->pPage,pCur->ix,&pCur->info); + }else{ + ; + } +} +# 4525 "src/btree.c" +int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){ + assert( pCur!=0 ); + return pCur->eState==0; +} + + + + + + + +i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==0 ); + assert( pCur->curIntKey ); + getCellInfo(pCur); + return pCur->info.nKey; +} +# 4567 "src/btree.c" +u32 sqlite3BtreePayloadSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==0 ); + getCellInfo(pCur); + return pCur->info.nPayload; +} +# 4587 "src/btree.c" +sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==0 ); + return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage; +} +# 4612 "src/btree.c" +static int getOverflowPage( + BtShared *pBt, + Pgno ovfl, + MemPage **ppPage, + Pgno *pPgnoNext +){ + Pgno next = 0; + MemPage *pPage = 0; + int rc = 0; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert(pPgnoNext); +# 4632 "src/btree.c" + if( pBt->autoVacuum ){ + Pgno pgno; + Pgno iGuess = ovfl+1; + u8 eType; + + while( (ptrmapPageno((pBt), (iGuess))==(iGuess)) || iGuess==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ + iGuess++; + } + + if( iGuess<=btreePagecount(pBt) ){ + rc = ptrmapGet(pBt, iGuess, &eType, &pgno); + if( rc==0 && eType==4 && pgno==ovfl ){ + next = iGuess; + rc = 101; + } + } + } + + + assert( next==0 || rc==101 ); + if( rc==0 ){ + rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? 0x02 : 0); + assert( rc==0 || pPage==0 ); + if( rc==0 ){ + next = sqlite3Get4byte(pPage->aData); + } + } + + *pPgnoNext = next; + if( ppPage ){ + *ppPage = pPage; + }else{ + releasePage(pPage); + } + return (rc==101 ? 0 : rc); +} +# 4680 "src/btree.c" +static int copyPayload( + void *pPayload, + void *pBuf, + int nByte, + int eOp, + DbPage *pDbPage +){ + if( eOp ){ + + int rc = sqlite3PagerWrite(pDbPage); + if( rc!=0 ){ + return rc; + } + memcpy(pPayload, pBuf, nByte); + }else{ + + memcpy(pBuf, pPayload, nByte); + } + return 0; +} +# 4730 "src/btree.c" +static int accessPayload( + BtCursor *pCur, + u32 offset, + u32 amt, + unsigned char *pBuf, + int eOp +){ + unsigned char *aPayload; + int rc = 0; + int iIdx = 0; + MemPage *pPage = pCur->pPage; + BtShared *pBt = pCur->pBt; + + + + + assert( pPage ); + assert( eOp==0 || eOp==1 ); + assert( pCur->eState==0 ); + assert( pCur->ix<pPage->nCell ); + assert( cursorHoldsMutex(pCur) ); + + getCellInfo(pCur); + aPayload = pCur->info.pPayload; + assert( offset+amt <= pCur->info.nPayload ); + + assert( aPayload > pPage->aData ); + if( (uptr)(aPayload - pPage->aData) > (pBt->usableSize - pCur->info.nLocal) ){ + + + + + + return sqlite3CorruptError(4763); + } + + + if( offset<pCur->info.nLocal ){ + int a = amt; + if( a+offset>pCur->info.nLocal ){ + a = pCur->info.nLocal - offset; + } + rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage); + offset = 0; + pBuf += a; + amt -= a; + }else{ + offset -= pCur->info.nLocal; + } + + + if( rc==0 && amt>0 ){ + const u32 ovflSize = pBt->usableSize - 4; + Pgno nextPage; + + nextPage = sqlite3Get4byte(&aPayload[pCur->info.nLocal]); +# 4794 "src/btree.c" + if( (pCur->curFlags & 0x04)==0 ){ + int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; + if( pCur->aOverflow==0 + || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) + ){ + Pgno *aNew = (Pgno*)sqlite3Realloc( + pCur->aOverflow, nOvfl*2*sizeof(Pgno) + ); + if( aNew==0 ){ + return 7; + }else{ + pCur->aOverflow = aNew; + } + } + memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno)); + pCur->curFlags |= 0x04; + }else{ + + + + + if( pCur->aOverflow[offset/ovflSize] ){ + iIdx = (offset/ovflSize); + nextPage = pCur->aOverflow[iIdx]; + offset = (offset%ovflSize); + } + } + + assert( rc==0 && amt>0 ); + while( nextPage ){ + + assert( pCur->aOverflow[iIdx]==0 + || pCur->aOverflow[iIdx]==nextPage + || (sqlite3Config.neverCorrupt==0) ); + pCur->aOverflow[iIdx] = nextPage; + + if( offset>=ovflSize ){ + + + + + + + assert( pCur->curFlags & 0x04 ); + assert( pCur->pBtree->db==pBt->db ); + if( pCur->aOverflow[iIdx+1] ){ + nextPage = pCur->aOverflow[iIdx+1]; + }else{ + rc = getOverflowPage(pBt, nextPage, 0, &nextPage); + } + offset -= ovflSize; + }else{ + + + + int a = amt; + if( a + offset > ovflSize ){ + a = ovflSize - offset; + } +# 4884 "src/btree.c" + { + DbPage *pDbPage; + rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, + (eOp==0 ? 0x02 : 0) + ); + if( rc==0 ){ + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = sqlite3Get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + sqlite3PagerUnref(pDbPage); + offset = 0; + } + } + amt -= a; + if( amt==0 ) return rc; + pBuf += a; + } + if( rc ) break; + iIdx++; + } + } + + if( rc==0 && amt>0 ){ + + return sqlite3CorruptError(4908); + } + return rc; +} +# 4930 "src/btree.c" +int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==0 ); + assert( pCur->iPage>=0 && pCur->pPage ); + assert( pCur->ix<pCur->pPage->nCell ); + return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); +} + + + + + + + +static int accessPayloadChecked( + BtCursor *pCur, + u32 offset, + u32 amt, + void *pBuf +){ + int rc; + if ( pCur->eState==1 ){ + return 4; + } + assert( cursorOwnsBtShared(pCur) ); + rc = btreeRestoreCursorPosition(pCur); + return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0); +} +int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ + if( pCur->eState==0 ){ + assert( cursorOwnsBtShared(pCur) ); + return accessPayload(pCur, offset, amt, pBuf, 0); + }else{ + return accessPayloadChecked(pCur, offset, amt, pBuf); + } +} +# 4987 "src/btree.c" +static const void *fetchPayload( + BtCursor *pCur, + u32 *pAmt +){ + int amt; + assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage); + assert( pCur->eState==0 ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->ix<pCur->pPage->nCell ); + assert( pCur->info.nSize>0 ); + assert( pCur->info.pPayload>pCur->pPage->aData || (sqlite3Config.neverCorrupt==0) ); + assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||(sqlite3Config.neverCorrupt==0)); + amt = pCur->info.nLocal; + if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){ + + + assert( (sqlite3Config.neverCorrupt==0) ); + amt = ((0)>((int)(pCur->pPage->aDataEnd - pCur->info.pPayload))?(0):((int)(pCur->pPage->aDataEnd - pCur->info.pPayload))); + } + *pAmt = (u32)amt; + return (void*)pCur->info.pPayload; +} +# 5026 "src/btree.c" +const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ + return fetchPayload(pCur, pAmt); +} +# 5040 "src/btree.c" +static int moveToChild(BtCursor *pCur, u32 newPgno){ + BtShared *pBt = pCur->pBt; + + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==0 ); + assert( pCur->iPage<20 ); + assert( pCur->iPage>=0 ); + if( pCur->iPage>=(20 -1) ){ + return sqlite3CorruptError(5048); + } + pCur->info.nSize = 0; + pCur->curFlags &= ~(0x02|0x04); + pCur->aiIdx[pCur->iPage] = pCur->ix; + pCur->apPage[pCur->iPage] = pCur->pPage; + pCur->ix = 0; + pCur->iPage++; + return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); +} +# 5089 "src/btree.c" +static void moveToParent(BtCursor *pCur){ + MemPage *pLeaf; + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==0 ); + assert( pCur->iPage>0 ); + assert( pCur->pPage ); + + + + + ; + ; + pCur->info.nSize = 0; + pCur->curFlags &= ~(0x02|0x04); + pCur->ix = pCur->aiIdx[pCur->iPage-1]; + pLeaf = pCur->pPage; + pCur->pPage = pCur->apPage[--pCur->iPage]; + releasePageNotNull(pLeaf); +} +# 5130 "src/btree.c" +static int moveToRoot(BtCursor *pCur){ + MemPage *pRoot; + int rc = 0; + + assert( cursorOwnsBtShared(pCur) ); + assert( 1 < 3 ); + assert( 0 < 3 ); + assert( 4 > 3 ); + assert( pCur->eState < 3 || pCur->iPage<0 ); + assert( pCur->pgnoRoot>0 || pCur->iPage<0 ); + + if( pCur->iPage>=0 ){ + if( pCur->iPage ){ + releasePageNotNull(pCur->pPage); + while( --pCur->iPage ){ + releasePageNotNull(pCur->apPage[pCur->iPage]); + } + pCur->pPage = pCur->apPage[0]; + goto skip_init; + } + }else if( pCur->pgnoRoot==0 ){ + pCur->eState = 1; + return 16; + }else{ + assert( pCur->iPage==(-1) ); + if( pCur->eState>=3 ){ + if( pCur->eState==4 ){ + assert( pCur->skipNext!=0 ); + return pCur->skipNext; + } + sqlite3BtreeClearCursor(pCur); + } + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, + 0, pCur->curPagerFlags); + if( rc!=0 ){ + pCur->eState = 1; + return rc; + } + pCur->iPage = 0; + pCur->curIntKey = pCur->pPage->intKey; + } + pRoot = pCur->pPage; + assert( pRoot->pgno==pCur->pgnoRoot ); +# 5184 "src/btree.c" + assert( pRoot->intKey==1 || pRoot->intKey==0 ); + if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ + return sqlite3CorruptError(5186); + } + +skip_init: + pCur->ix = 0; + pCur->info.nSize = 0; + pCur->curFlags &= ~(0x08|0x02|0x04); + + pRoot = pCur->pPage; + if( pRoot->nCell>0 ){ + pCur->eState = 0; + }else if( !pRoot->leaf ){ + Pgno subpage; + if( pRoot->pgno!=1 ) return sqlite3CorruptError(5199); + subpage = sqlite3Get4byte(&pRoot->aData[pRoot->hdrOffset+8]); + pCur->eState = 0; + rc = moveToChild(pCur, subpage); + }else{ + pCur->eState = 1; + rc = 16; + } + return rc; +} +# 5217 "src/btree.c" +static int moveToLeftmost(BtCursor *pCur){ + Pgno pgno; + int rc = 0; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==0 ); + while( rc==0 && !(pPage = pCur->pPage)->leaf ){ + assert( pCur->ix<pPage->nCell ); + pgno = sqlite3Get4byte(((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(pCur->ix)]))))); + rc = moveToChild(pCur, pgno); + } + return rc; +} +# 5242 "src/btree.c" +static int moveToRightmost(BtCursor *pCur){ + Pgno pgno; + int rc = 0; + MemPage *pPage = 0; + + assert( cursorOwnsBtShared(pCur) ); + assert( pCur->eState==0 ); + while( !(pPage = pCur->pPage)->leaf ){ + pgno = sqlite3Get4byte(&pPage->aData[pPage->hdrOffset+8]); + pCur->ix = pPage->nCell; + rc = moveToChild(pCur, pgno); + if( rc ) return rc; + } + pCur->ix = pPage->nCell-1; + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & 0x02)==0 ); + return 0; +} + + + + + +int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + rc = moveToRoot(pCur); + if( rc==0 ){ + assert( pCur->pPage->nCell>0 ); + *pRes = 0; + rc = moveToLeftmost(pCur); + }else if( rc==16 ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = 0; + } + return rc; +} + + + + + +int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ + int rc; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + + if( 0==pCur->eState && (pCur->curFlags & 0x08)!=0 ){ +# 5305 "src/btree.c" + *pRes = 0; + return 0; + } + + rc = moveToRoot(pCur); + if( rc==0 ){ + assert( pCur->eState==0 ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==0 ){ + pCur->curFlags |= 0x08; + }else{ + pCur->curFlags &= ~0x08; + } + }else if( rc==16 ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = 1; + rc = 0; + } + return rc; +} +# 5357 "src/btree.c" +int sqlite3BtreeMovetoUnpacked( + BtCursor *pCur, + UnpackedRecord *pIdxKey, + i64 intKey, + int biasRight, + int *pRes +){ + int rc; + RecordCompare xRecordCompare; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); + assert( pCur->eState!=0 || (pIdxKey==0)==(pCur->curIntKey!=0) ); + + + + if( pIdxKey==0 + && pCur->eState==0 && (pCur->curFlags & 0x02)!=0 + ){ + if( pCur->info.nKey==intKey ){ + *pRes = 0; + return 0; + } + if( pCur->info.nKey<intKey ){ + if( (pCur->curFlags & 0x08)!=0 ){ + *pRes = -1; + return 0; + } + + + + + if( pCur->info.nKey+1==intKey ){ + *pRes = 0; + rc = sqlite3BtreeNext(pCur, 0); + if( rc==0 ){ + getCellInfo(pCur); + if( pCur->info.nKey==intKey ){ + return 0; + } + }else if( rc==101 ){ + rc = 0; + }else{ + return rc; + } + } + } + } + + if( pIdxKey ){ + xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); + pIdxKey->errCode = 0; + assert( pIdxKey->default_rc==1 + || pIdxKey->default_rc==0 + || pIdxKey->default_rc==-1 + ); + }else{ + xRecordCompare = 0; + } + + rc = moveToRoot(pCur); + if( rc ){ + if( rc==16 ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = -1; + return 0; + } + return rc; + } + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); + assert( pCur->eState==0 ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); + assert( pCur->curIntKey || pIdxKey ); + for(;;){ + int lwr, upr, idx, c; + Pgno chldPg; + MemPage *pPage = pCur->pPage; + u8 *pCell; + + + + + + + + assert( pPage->nCell>0 ); + assert( pPage->intKey==(pIdxKey==0) ); + lwr = 0; + upr = pPage->nCell-1; + assert( biasRight==0 || biasRight==1 ); + idx = upr>>(1-biasRight); + pCur->ix = (u16)idx; + if( xRecordCompare==0 ){ + for(;;){ + i64 nCellKey; + pCell = ((pPage)->aDataOfst + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(idx)])))); + if( pPage->intKeyLeaf ){ + while( 0x80 <= *(pCell++) ){ + if( pCell>=pPage->aDataEnd ){ + return sqlite3CorruptError(5460); + } + } + } + sqlite3GetVarint(pCell, (u64*)&nCellKey); + if( nCellKey<intKey ){ + lwr = idx+1; + if( lwr>upr ){ c = -1; break; } + }else if( nCellKey>intKey ){ + upr = idx-1; + if( lwr>upr ){ c = +1; break; } + }else{ + assert( nCellKey==intKey ); + pCur->ix = (u16)idx; + if( !pPage->leaf ){ + lwr = idx; + goto moveto_next_layer; + }else{ + pCur->curFlags |= 0x02; + pCur->info.nKey = nCellKey; + pCur->info.nSize = 0; + *pRes = 0; + return 0; + } + } + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; + } + }else{ + for(;;){ + int nCell; + pCell = ((pPage)->aDataOfst + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(idx)])))); +# 5501 "src/btree.c" + nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload ){ + + + + ; + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + ){ + + + ; + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ +# 5525 "src/btree.c" + void *pCellKey; + u8 * const pCellBody = pCell - pPage->childPtrSize; + const int nOverrun = 18; + pPage->xParseCell(pPage, pCellBody, &pCur->info); + nCell = (int)pCur->info.nKey; + ; + ; + ; + ; + if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){ + rc = sqlite3CorruptError(5535); + goto moveto_finish; + } + pCellKey = sqlite3Malloc( nCell+nOverrun ); + if( pCellKey==0 ){ + rc = 7; + goto moveto_finish; + } + pCur->ix = (u16)idx; + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + memset(((u8*)pCellKey)+nCell,0,nOverrun); + pCur->curFlags &= ~0x04; + if( rc ){ + sqlite3_free(pCellKey); + goto moveto_finish; + } + c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); + sqlite3_free(pCellKey); + } + assert( + (pIdxKey->errCode!=11 || c==0) + && (pIdxKey->errCode!=7 || pCur->pBtree->db->mallocFailed) + ); + if( c<0 ){ + lwr = idx+1; + }else if( c>0 ){ + upr = idx-1; + }else{ + assert( c==0 ); + *pRes = 0; + rc = 0; + pCur->ix = (u16)idx; + if( pIdxKey->errCode ) rc = sqlite3CorruptError(5567); + goto moveto_finish; + } + if( lwr>upr ) break; + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; + } + } + assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); + assert( pPage->isInit ); + if( pPage->leaf ){ + assert( pCur->ix<pCur->pPage->nCell ); + pCur->ix = (u16)idx; + *pRes = c; + rc = 0; + goto moveto_finish; + } +moveto_next_layer: + if( lwr>=pPage->nCell ){ + chldPg = sqlite3Get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = sqlite3Get4byte(((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(lwr)]))))); + } + pCur->ix = (u16)lwr; + rc = moveToChild(pCur, chldPg); + if( rc ) break; + } +moveto_finish: + pCur->info.nSize = 0; + assert( (pCur->curFlags & 0x04)==0 ); + return rc; +} +# 5608 "src/btree.c" +int sqlite3BtreeEof(BtCursor *pCur){ + + + + + return (0!=pCur->eState); +} + + + + + + +i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ + i64 n; + u8 i; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + + + + + if( (pCur->eState!=0) ) return -1; + if( (pCur->pPage->leaf==0) ) return -1; + + n = pCur->pPage->nCell; + for(i=0; i<pCur->iPage; i++){ + n *= pCur->apPage[i]->nCell; + } + return n; +} +# 5661 "src/btree.c" +static int btreeNext(BtCursor *pCur){ + int rc; + int idx; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + if( pCur->eState!=0 ){ + assert( (pCur->curFlags & 0x04)==0 ); + rc = (pCur->eState>=3 ? btreeRestoreCursorPosition(pCur) : 0); + if( rc!=0 ){ + return rc; + } + if( 1==pCur->eState ){ + return 101; + } + if( pCur->eState==2 ){ + pCur->eState = 0; + if( pCur->skipNext>0 ) return 0; + } + } + + pPage = pCur->pPage; + idx = ++pCur->ix; + if( !pPage->isInit ){ + + + + + + + + return sqlite3CorruptError(5692); + } + + + + + + + ; + + if( idx>=pPage->nCell ){ + if( !pPage->leaf ){ + rc = moveToChild(pCur, sqlite3Get4byte(&pPage->aData[pPage->hdrOffset+8])); + if( rc ) return rc; + return moveToLeftmost(pCur); + } + do{ + if( pCur->iPage==0 ){ + pCur->eState = 1; + return 101; + } + moveToParent(pCur); + pPage = pCur->pPage; + }while( pCur->ix>=pPage->nCell ); + if( pPage->intKey ){ + return sqlite3BtreeNext(pCur, 0); + }else{ + return 0; + } + } + if( pPage->leaf ){ + return 0; + }else{ + return moveToLeftmost(pCur); + } +} +int sqlite3BtreeNext(BtCursor *pCur, int flags){ + MemPage *pPage; + (void)(flags); + assert( cursorOwnsBtShared(pCur) ); + assert( flags==0 || flags==1 ); + pCur->info.nSize = 0; + pCur->curFlags &= ~(0x02|0x04); + if( pCur->eState!=0 ) return btreeNext(pCur); + pPage = pCur->pPage; + if( (++pCur->ix)>=pPage->nCell ){ + pCur->ix--; + return btreeNext(pCur); + } + if( pPage->leaf ){ + return 0; + }else{ + return moveToLeftmost(pCur); + } +} +# 5768 "src/btree.c" +static int btreePrevious(BtCursor *pCur){ + int rc; + MemPage *pPage; + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & (0x08|0x04|0x02))==0 ); + assert( pCur->info.nSize==0 ); + if( pCur->eState!=0 ){ + rc = (pCur->eState>=3 ? btreeRestoreCursorPosition(pCur) : 0); + if( rc!=0 ){ + return rc; + } + if( 1==pCur->eState ){ + return 101; + } + if( 2==pCur->eState ){ + pCur->eState = 0; + if( pCur->skipNext<0 ) return 0; + } + } + + pPage = pCur->pPage; + assert( pPage->isInit ); + if( !pPage->leaf ){ + int idx = pCur->ix; + rc = moveToChild(pCur, sqlite3Get4byte(((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(idx)])))))); + if( rc ) return rc; + rc = moveToRightmost(pCur); + }else{ + while( pCur->ix==0 ){ + if( pCur->iPage==0 ){ + pCur->eState = 1; + return 101; + } + moveToParent(pCur); + } + assert( pCur->info.nSize==0 ); + assert( (pCur->curFlags & (0x04))==0 ); + + pCur->ix--; + pPage = pCur->pPage; + if( pPage->intKey && !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, 0); + }else{ + rc = 0; + } + } + return rc; +} +int sqlite3BtreePrevious(BtCursor *pCur, int flags){ + assert( cursorOwnsBtShared(pCur) ); + assert( flags==0 || flags==1 ); + (void)(flags); + pCur->curFlags &= ~(0x08|0x04|0x02); + pCur->info.nSize = 0; + if( pCur->eState!=0 + || pCur->ix==0 + || pCur->pPage->leaf==0 + ){ + return btreePrevious(pCur); + } + pCur->ix--; + return 0; +} +# 5855 "src/btree.c" +static int allocateBtreePage( + BtShared *pBt, + MemPage **ppPage, + Pgno *pPgno, + Pgno nearby, + u8 eMode +){ + MemPage *pPage1; + int rc; + u32 n; + u32 k; + MemPage *pTrunk = 0; + MemPage *pPrevTrunk = 0; + Pgno mxPage; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( eMode==0 || (nearby>0 && (pBt->autoVacuum)) ); + pPage1 = pBt->pPage1; + mxPage = btreePagecount(pBt); + + + n = sqlite3Get4byte(&pPage1->aData[36]); + ; + if( n>=mxPage ){ + return sqlite3CorruptError(5879); + } + if( n>0 ){ + + Pgno iTrunk; + u8 searchList = 0; + u32 nSearch = 0; + + + + + + + if( eMode==1 ){ + if( nearby<=mxPage ){ + u8 eType; + assert( nearby>0 ); + assert( pBt->autoVacuum ); + rc = ptrmapGet(pBt, nearby, &eType, 0); + if( rc ) return rc; + if( eType==2 ){ + searchList = 1; + } + } + }else if( eMode==2 ){ + searchList = 1; + } + + + + + + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) return rc; + sqlite3Put4byte(&pPage1->aData[36], n-1); + + + + + + + do { + pPrevTrunk = pTrunk; + if( pPrevTrunk ){ + + + + iTrunk = sqlite3Get4byte(&pPrevTrunk->aData[0]); + }else{ + + + + iTrunk = sqlite3Get4byte(&pPage1->aData[32]); + } + ; + if( iTrunk>mxPage || nSearch++ > n ){ + rc = sqlite3CorruptError(5935); + }else{ + rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0); + } + if( rc ){ + pTrunk = 0; + goto end_allocate_page; + } + assert( pTrunk!=0 ); + assert( pTrunk->aData!=0 ); + + + k = sqlite3Get4byte(&pTrunk->aData[4]); + if( k==0 && !searchList ){ + + + + assert( pPrevTrunk==0 ); + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + *pPgno = iTrunk; + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + *ppPage = pTrunk; + pTrunk = 0; + ; + }else if( k>(u32)(pBt->usableSize/4 - 2) ){ + + rc = sqlite3CorruptError(5964); + goto end_allocate_page; + + }else if( searchList + && (nearby==iTrunk || (iTrunk<nearby && eMode==2)) + ){ + + + + *pPgno = iTrunk; + *ppPage = pTrunk; + searchList = 0; + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + if( k==0 ){ + if( !pPrevTrunk ){ + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc!=0 ){ + goto end_allocate_page; + } + memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); + } + }else{ + + + + + MemPage *pNewTrunk; + Pgno iNewTrunk = sqlite3Get4byte(&pTrunk->aData[8]); + if( iNewTrunk>mxPage ){ + rc = sqlite3CorruptError(5998); + goto end_allocate_page; + } + ; + rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0); + if( rc!=0 ){ + goto end_allocate_page; + } + rc = sqlite3PagerWrite(pNewTrunk->pDbPage); + if( rc!=0 ){ + releasePage(pNewTrunk); + goto end_allocate_page; + } + memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); + sqlite3Put4byte(&pNewTrunk->aData[4], k-1); + memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + releasePage(pNewTrunk); + if( !pPrevTrunk ){ + assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); + sqlite3Put4byte(&pPage1->aData[32], iNewTrunk); + }else{ + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); + if( rc ){ + goto end_allocate_page; + } + sqlite3Put4byte(&pPrevTrunk->aData[0], iNewTrunk); + } + } + pTrunk = 0; + ; + + }else if( k>0 ){ + + u32 closest; + Pgno iPage; + unsigned char *aData = pTrunk->aData; + if( nearby>0 ){ + u32 i; + closest = 0; + if( eMode==2 ){ + for(i=0; i<k; i++){ + iPage = sqlite3Get4byte(&aData[8+i*4]); + if( iPage<=nearby ){ + closest = i; + break; + } + } + }else{ + int dist; + dist = sqlite3AbsInt32(sqlite3Get4byte(&aData[8]) - nearby); + for(i=1; i<k; i++){ + int d2 = sqlite3AbsInt32(sqlite3Get4byte(&aData[8+i*4]) - nearby); + if( d2<dist ){ + closest = i; + dist = d2; + } + } + } + }else{ + closest = 0; + } + + iPage = sqlite3Get4byte(&aData[8+closest*4]); + ; + if( iPage>mxPage ){ + rc = sqlite3CorruptError(6063); + goto end_allocate_page; + } + ; + if( !searchList + || (iPage==nearby || (iPage<nearby && eMode==2)) + ){ + int noContent; + *pPgno = iPage; + + + ; + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc ) goto end_allocate_page; + if( closest<k-1 ){ + memcpy(&aData[8+closest*4], &aData[4+k*4], 4); + } + sqlite3Put4byte(&aData[4], k-1); + noContent = !btreeGetHasContent(pBt, *pPgno)? 0x01 : 0; + rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, noContent); + if( rc==0 ){ + rc = sqlite3PagerWrite((*ppPage)->pDbPage); + if( rc!=0 ){ + releasePage(*ppPage); + *ppPage = 0; + } + } + searchList = 0; + } + } + releasePage(pPrevTrunk); + pPrevTrunk = 0; + }while( searchList ); + }else{ +# 6115 "src/btree.c" + int bNoContent = (0==(pBt->bDoTruncate))? 0x01:0; + + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ) pBt->nPage++; + + + if( pBt->autoVacuum && (ptrmapPageno((pBt), (pBt->nPage))==(pBt->nPage)) ){ + + + + + MemPage *pPg = 0; + ; + assert( pBt->nPage!=((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ); + rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); + if( rc==0 ){ + rc = sqlite3PagerWrite(pPg->pDbPage); + releasePage(pPg); + } + if( rc ) return rc; + pBt->nPage++; + if( pBt->nPage==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ pBt->nPage++; } + } + + sqlite3Put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); + *pPgno = pBt->nPage; + + assert( *pPgno!=((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ); + rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent); + if( rc ) return rc; + rc = sqlite3PagerWrite((*ppPage)->pDbPage); + if( rc!=0 ){ + releasePage(*ppPage); + *ppPage = 0; + } + ; + } + + assert( (sqlite3Config.neverCorrupt==0) || *pPgno!=((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ); + +end_allocate_page: + releasePage(pTrunk); + releasePage(pPrevTrunk); + assert( rc!=0 || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 ); + assert( rc!=0 || (*ppPage)->isInit==0 ); + return rc; +} +# 6177 "src/btree.c" +static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ + MemPage *pTrunk = 0; + Pgno iTrunk = 0; + MemPage *pPage1 = pBt->pPage1; + MemPage *pPage; + int rc; + u32 nFree; + + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( (sqlite3Config.neverCorrupt==0) || iPage>1 ); + assert( !pMemPage || pMemPage->pgno==iPage ); + + if( iPage<2 || iPage>pBt->nPage ){ + return sqlite3CorruptError(6190); + } + if( pMemPage ){ + pPage = pMemPage; + sqlite3PagerRef(pPage->pDbPage); + }else{ + pPage = btreePageLookup(pBt, iPage); + } + + + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc ) goto freepage_out; + nFree = sqlite3Get4byte(&pPage1->aData[36]); + sqlite3Put4byte(&pPage1->aData[36], nFree+1); + + if( pBt->btsFlags & 0x0004 ){ + + + + if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) + || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) + ){ + goto freepage_out; + } + memset(pPage->aData, 0, pPage->pBt->pageSize); + } + + + + + if( (pBt->autoVacuum) ){ + ptrmapPut(pBt, iPage, 2, 0, &rc); + if( rc ) goto freepage_out; + } +# 6232 "src/btree.c" + if( nFree!=0 ){ + u32 nLeaf; + + iTrunk = sqlite3Get4byte(&pPage1->aData[32]); + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); + if( rc!=0 ){ + goto freepage_out; + } + + nLeaf = sqlite3Get4byte(&pTrunk->aData[4]); + assert( pBt->usableSize>32 ); + if( nLeaf > (u32)pBt->usableSize/4 - 2 ){ + rc = sqlite3CorruptError(6244); + goto freepage_out; + } + if( nLeaf < (u32)pBt->usableSize/4 - 8 ){ +# 6267 "src/btree.c" + rc = sqlite3PagerWrite(pTrunk->pDbPage); + if( rc==0 ){ + sqlite3Put4byte(&pTrunk->aData[4], nLeaf+1); + sqlite3Put4byte(&pTrunk->aData[8+nLeaf*4], iPage); + if( pPage && (pBt->btsFlags & 0x0004)==0 ){ + sqlite3PagerDontWrite(pPage->pDbPage); + } + rc = btreeSetHasContent(pBt, iPage); + } + ; + goto freepage_out; + } + } + + + + + + + + if( pPage==0 && 0!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ + goto freepage_out; + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=0 ){ + goto freepage_out; + } + sqlite3Put4byte(pPage->aData, iTrunk); + sqlite3Put4byte(&pPage->aData[4], 0); + sqlite3Put4byte(&pPage1->aData[32], iPage); + ; + +freepage_out: + if( pPage ){ + pPage->isInit = 0; + } + releasePage(pPage); + releasePage(pTrunk); + return rc; +} +static void freePage(MemPage *pPage, int *pRC){ + if( (*pRC)==0 ){ + *pRC = freePage2(pPage->pBt, pPage, pPage->pgno); + } +} + + + + + +static int clearCell( + MemPage *pPage, + unsigned char *pCell, + CellInfo *pInfo +){ + BtShared *pBt; + Pgno ovflPgno; + int rc; + int nOvfl; + u32 ovflPageSize; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + pPage->xParseCell(pPage, pCell, pInfo); + if( pInfo->nLocal==pInfo->nPayload ){ + return 0; + } + ; + ; + if( pCell + pInfo->nSize > pPage->aDataEnd ){ + + return sqlite3CorruptError(6337); + } + ovflPgno = sqlite3Get4byte(pCell + pInfo->nSize - 4); + pBt = pPage->pBt; + assert( pBt->usableSize > 4 ); + ovflPageSize = pBt->usableSize - 4; + nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize; + assert( nOvfl>0 || + ((sqlite3Config.neverCorrupt==0) && (pInfo->nPayload + ovflPageSize)<ovflPageSize) + ); + while( nOvfl-- ){ + Pgno iNext = 0; + MemPage *pOvfl = 0; + if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){ + + + + return sqlite3CorruptError(6354); + } + if( nOvfl ){ + rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext); + if( rc ) return rc; + } + + if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) + && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 + ){ +# 6374 "src/btree.c" + rc = sqlite3CorruptError(6374); + }else{ + rc = freePage2(pBt, pOvfl, ovflPgno); + } + + if( pOvfl ){ + sqlite3PagerUnref(pOvfl->pDbPage); + } + if( rc ) return rc; + ovflPgno = iNext; + } + return 0; +} +# 6400 "src/btree.c" +static int fillInCell( + MemPage *pPage, + unsigned char *pCell, + const BtreePayload *pX, + int *pnSize +){ + int nPayload; + const u8 *pSrc; + int nSrc, n, rc, mn; + int spaceLeft; + MemPage *pToRelease; + unsigned char *pPrior; + unsigned char *pPayload; + BtShared *pBt; + Pgno pgnoOvfl; + int nHeader; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + + + + assert( pCell<pPage->aData || pCell>=&pPage->aData[pPage->pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + + nHeader = pPage->childPtrSize; + if( pPage->intKey ){ + nPayload = pX->nData + pX->nZero; + pSrc = pX->pData; + nSrc = pX->nData; + assert( pPage->intKeyLeaf ); + nHeader += (u8)(((u32)(nPayload)<(u32)0x80)?(*(&pCell[nHeader])=(unsigned char)(nPayload)),1: sqlite3PutVarint((&pCell[nHeader]),(nPayload))); + nHeader += sqlite3PutVarint(&pCell[nHeader], *(u64*)&pX->nKey); + }else{ + assert( pX->nKey<=0x7fffffff && pX->pKey!=0 ); + nSrc = nPayload = (int)pX->nKey; + pSrc = pX->pKey; + nHeader += (u8)(((u32)(nPayload)<(u32)0x80)?(*(&pCell[nHeader])=(unsigned char)(nPayload)),1: sqlite3PutVarint((&pCell[nHeader]),(nPayload))); + } + + + pPayload = &pCell[nHeader]; + if( nPayload<=pPage->maxLocal ){ + + + n = nHeader + nPayload; + ; + ; + if( n<4 ) n = 4; + *pnSize = n; + assert( nSrc<=nPayload ); + ; + memcpy(pPayload, pSrc, nSrc); + memset(pPayload+nSrc, 0, nPayload-nSrc); + return 0; + } + + + + + mn = pPage->minLocal; + n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); + ; + ; + if( n > pPage->maxLocal ) n = mn; + spaceLeft = n; + *pnSize = n + nHeader + 4; + pPrior = &pCell[nHeader+n]; + pToRelease = 0; + pgnoOvfl = 0; + pBt = pPage->pBt; +# 6496 "src/btree.c" + while( 1 ){ + n = nPayload; + if( n>spaceLeft ) n = spaceLeft; + + + + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + + + assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + if( nSrc>=n ){ + memcpy(pPayload, pSrc, n); + }else if( nSrc>0 ){ + n = nSrc; + memcpy(pPayload, pSrc, n); + }else{ + memset(pPayload, 0, n); + } + nPayload -= n; + if( nPayload<=0 ) break; + pPayload += n; + pSrc += n; + nSrc -= n; + spaceLeft -= n; + if( spaceLeft==0 ){ + MemPage *pOvfl = 0; + + Pgno pgnoPtrmap = pgnoOvfl; + if( pBt->autoVacuum ){ + do{ + pgnoOvfl++; + } while( + (ptrmapPageno((pBt), (pgnoOvfl))==(pgnoOvfl)) || pgnoOvfl==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) + ); + } + + rc = allocateBtreePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); +# 6547 "src/btree.c" + if( pBt->autoVacuum && rc==0 ){ + u8 eType = (pgnoPtrmap?4:3); + ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc); + if( rc ){ + releasePage(pOvfl); + } + } + + if( rc ){ + releasePage(pToRelease); + return rc; + } + + + + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + + + assert( pPrior<pPage->aData || pPrior>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + sqlite3Put4byte(pPrior, pgnoOvfl); + releasePage(pToRelease); + pToRelease = pOvfl; + pPrior = pOvfl->aData; + sqlite3Put4byte(pPrior, 0); + pPayload = &pOvfl->aData[4]; + spaceLeft = pBt->usableSize - 4; + } + } + releasePage(pToRelease); + return 0; +} +# 6590 "src/btree.c" +static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ + u32 pc; + u8 *data; + u8 *ptr; + int rc; + int hdr; + + if( *pRC ) return; + assert( idx>=0 && idx<pPage->nCell ); + assert( (sqlite3Config.neverCorrupt==0) || sz==cellSize(pPage, idx) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->nFree>=0 ); + data = pPage->aData; + ptr = &pPage->aCellIdx[2*idx]; + pc = ((ptr)[0]<<8 | (ptr)[1]); + hdr = pPage->hdrOffset; + ; + ; + if( pc+sz > pPage->pBt->usableSize ){ + *pRC = sqlite3CorruptError(6610); + return; + } + rc = freeSpace(pPage, pc, sz); + if( rc ){ + *pRC = rc; + return; + } + pPage->nCell--; + if( pPage->nCell==0 ){ + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + ((&data[hdr+5])[0] = (u8)((pPage->pBt->usableSize)>>8), (&data[hdr+5])[1] = (u8)(pPage->pBt->usableSize)); + pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset + - pPage->childPtrSize - 8; + }else{ + memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); + ((&data[hdr+3])[0] = (u8)((pPage->nCell)>>8), (&data[hdr+3])[1] = (u8)(pPage->nCell)); + pPage->nFree += 2; + } +} +# 6646 "src/btree.c" +static void insertCell( + MemPage *pPage, + int i, + u8 *pCell, + int sz, + u8 *pTemp, + Pgno iChild, + int *pRC +){ + int idx = 0; + int j; + u8 *data; + u8 *pIns; + + assert( *pRC==0 ); + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); + assert( ((pPage->pBt->pageSize-8)/6)<=10921 ); + assert( pPage->nCell<=((pPage->pBt->pageSize-8)/6) || (sqlite3Config.neverCorrupt==0) ); + assert( pPage->nOverflow<=((int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0]))) ); + assert( ((int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])))==((int)(sizeof(pPage->aiOvfl)/sizeof(pPage->aiOvfl[0]))) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + + + + + + assert( sz==pPage->xCellSize(pPage, pCell) || (sz==8 && iChild>0) ); + assert( pPage->nFree>=0 ); + if( pPage->nOverflow || sz+2>pPage->nFree ){ + if( pTemp ){ + memcpy(pTemp, pCell, sz); + pCell = pTemp; + } + if( iChild ){ + sqlite3Put4byte(pCell, iChild); + } + j = pPage->nOverflow++; + + + + assert( j < ((int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])))-1 ); + pPage->apOvfl[j] = pCell; + pPage->aiOvfl[j] = (u16)i; + + + + + + + assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); + assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); + }else{ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=0 ){ + *pRC = rc; + return; + } + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + data = pPage->aData; + assert( &data[pPage->cellOffset]==pPage->aCellIdx ); + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ *pRC = rc; return; } + + + assert( idx >= 0 ); + assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || (sqlite3Config.neverCorrupt==0) ); + assert( idx+sz <= (int)pPage->pBt->usableSize ); + pPage->nFree -= (u16)(2 + sz); + if( iChild ){ + + + + + + memcpy(&data[idx+4], pCell+4, sz-4); + sqlite3Put4byte(&data[idx], iChild); + }else{ + memcpy(&data[idx], pCell, sz); + } + pIns = pPage->aCellIdx + i*2; + memmove(pIns+2, pIns, 2*(pPage->nCell - i)); + ((pIns)[0] = (u8)((idx)>>8), (pIns)[1] = (u8)(idx)); + pPage->nCell++; + + if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++; + assert( ((&data[pPage->hdrOffset+3])[0]<<8 | (&data[pPage->hdrOffset+3])[1])==pPage->nCell || (sqlite3Config.neverCorrupt==0) ); + + if( pPage->pBt->autoVacuum ){ + + + + ptrmapPutOvflPtr(pPage, pPage, pCell, pRC); + } + + } +} +# 6826 "src/btree.c" +typedef struct CellArray CellArray; +struct CellArray { + int nCell; + MemPage *pRef; + u8 **apCell; + u16 *szCell; + u8 *apEnd[3*2]; + int ixNx[3*2]; +}; + + + + + +static void populateCellCache(CellArray *p, int idx, int N){ + assert( idx>=0 && idx+N<=p->nCell ); + while( N>0 ){ + assert( p->apCell[idx]!=0 ); + if( p->szCell[idx]==0 ){ + p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]); + }else{ + assert( (sqlite3Config.neverCorrupt==0) || + p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) ); + } + idx++; + N--; + } +} + + + + +static u16 computeCellSize(CellArray *p, int N){ + assert( N>=0 && N<p->nCell ); + assert( p->szCell[N]==0 ); + p->szCell[N] = p->pRef->xCellSize(p->pRef, p->apCell[N]); + return p->szCell[N]; +} +static u16 cachedCellSize(CellArray *p, int N){ + assert( N>=0 && N<p->nCell ); + if( p->szCell[N] ) return p->szCell[N]; + return computeCellSize(p, N); +} +# 6883 "src/btree.c" +static int rebuildPage( + CellArray *pCArray, + int iFirst, + int nCell, + MemPage *pPg +){ + const int hdr = pPg->hdrOffset; + u8 * const aData = pPg->aData; + const int usableSize = pPg->pBt->usableSize; + u8 * const pEnd = &aData[usableSize]; + int i = iFirst; + u32 j; + int iEnd = i+nCell; + u8 *pCellptr = pPg->aCellIdx; + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); + u8 *pData; + int k; + u8 *pSrcEnd; + + assert( i<iEnd ); + j = ((&aData[hdr+5])[0]<<8 | (&aData[hdr+5])[1]); + if( (j>(u32)usableSize) ){ j = 0; } + memcpy(&pTmp[j], &aData[j], usableSize - j); + + for(k=0; pCArray->ixNx[k]<=i && (k<3*2); k++){} + pSrcEnd = pCArray->apEnd[k]; + + pData = pEnd; + while( 1 ){ + u8 *pCell = pCArray->apCell[i]; + u16 sz = pCArray->szCell[i]; + assert( sz>0 ); + if( (((uptr)(pCell)>=(uptr)(aData))&&((uptr)(pCell)<(uptr)(pEnd))) ){ + if( ((uptr)(pCell+sz))>(uptr)pEnd ) return sqlite3CorruptError(6916); + pCell = &pTmp[pCell - aData]; + }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd + && (uptr)(pCell)<(uptr)pSrcEnd + ){ + return sqlite3CorruptError(6921); + } + + pData -= sz; + ((pCellptr)[0] = (u8)(((pData - aData))>>8), (pCellptr)[1] = (u8)((pData - aData))); + pCellptr += 2; + if( pData < pCellptr ) return sqlite3CorruptError(6927); + memcpy(pData, pCell, sz); + assert( sz==pPg->xCellSize(pPg, pCell) || (sqlite3Config.neverCorrupt==0) ); + ; + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pSrcEnd = pCArray->apEnd[k]; + } + } + + + pPg->nCell = nCell; + pPg->nOverflow = 0; + + ((&aData[hdr+1])[0] = (u8)((0)>>8), (&aData[hdr+1])[1] = (u8)(0)); + ((&aData[hdr+3])[0] = (u8)((pPg->nCell)>>8), (&aData[hdr+3])[1] = (u8)(pPg->nCell)); + ((&aData[hdr+5])[0] = (u8)((pData - aData)>>8), (&aData[hdr+5])[1] = (u8)(pData - aData)); + aData[hdr+7] = 0x00; + return 0; +} +# 6974 "src/btree.c" +static int pageInsertArray( + MemPage *pPg, + u8 *pBegin, + u8 **ppData, + u8 *pCellptr, + int iFirst, + int nCell, + CellArray *pCArray +){ + int i = iFirst; + u8 *aData = pPg->aData; + u8 *pData = *ppData; + int iEnd = iFirst + nCell; + int k; + u8 *pEnd; + assert( (sqlite3Config.neverCorrupt==0) || pPg->hdrOffset==0 ); + if( iEnd<=iFirst ) return 0; + for(k=0; pCArray->ixNx[k]<=i && (k<3*2); k++){} + pEnd = pCArray->apEnd[k]; + while( 1 ){ + int sz, rc; + u8 *pSlot; + sz = cachedCellSize(pCArray, i); + if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){ + if( (pData - pBegin)<sz ) return 1; + pData -= sz; + pSlot = pData; + } + + + + assert( (pSlot+sz)<=pCArray->apCell[i] + || pSlot>=(pCArray->apCell[i]+sz) + || (sqlite3Config.neverCorrupt==0) ); + if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd + && (uptr)(pCArray->apCell[i])<(uptr)pEnd + ){ + assert( (sqlite3Config.neverCorrupt==0) ); + (void)sqlite3CorruptError(7012); + return 1; + } + memmove(pSlot, pCArray->apCell[i], sz); + ((pCellptr)[0] = (u8)(((pSlot - aData))>>8), (pCellptr)[1] = (u8)((pSlot - aData))); + pCellptr += 2; + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pEnd = pCArray->apEnd[k]; + } + } + *ppData = pData; + return 0; +} +# 7038 "src/btree.c" +static int pageFreeArray( + MemPage *pPg, + int iFirst, + int nCell, + CellArray *pCArray +){ + u8 * const aData = pPg->aData; + u8 * const pEnd = &aData[pPg->pBt->usableSize]; + u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize]; + int nRet = 0; + int i; + int iEnd = iFirst + nCell; + u8 *pFree = 0; + int szFree = 0; + + for(i=iFirst; i<iEnd; i++){ + u8 *pCell = pCArray->apCell[i]; + if( (((uptr)(pCell)>=(uptr)(pStart))&&((uptr)(pCell)<(uptr)(pEnd))) ){ + int sz; + + + + sz = pCArray->szCell[i]; assert( sz>0 ); + if( pFree!=(pCell + sz) ){ + if( pFree ){ + assert( pFree>aData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); + } + pFree = pCell; + szFree = sz; + if( pFree+sz>pEnd ) return 0; + }else{ + pFree = pCell; + szFree += sz; + } + nRet++; + } + } + if( pFree ){ + assert( pFree>aData && (pFree - aData)<65536 ); + freeSpace(pPg, (u16)(pFree - aData), szFree); + } + return nRet; +} +# 7095 "src/btree.c" +static int editPage( + MemPage *pPg, + int iOld, + int iNew, + int nNew, + CellArray *pCArray +){ + u8 * const aData = pPg->aData; + const int hdr = pPg->hdrOffset; + u8 *pBegin = &pPg->aCellIdx[nNew * 2]; + int nCell = pPg->nCell; + u8 *pData; + u8 *pCellptr; + int i; + int iOldEnd = iOld + pPg->nCell + pPg->nOverflow; + int iNewEnd = iNew + nNew; + + + + + + + + assert( nCell>=0 ); + if( iOld<iNew ){ + int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray); + if( nShift>nCell ) return sqlite3CorruptError(7121); + memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2); + nCell -= nShift; + } + if( iNewEnd < iOldEnd ){ + int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray); + assert( nCell>=nTail ); + nCell -= nTail; + } + + pData = &aData[(((((int)((&aData[hdr+5])[0]<<8 | (&aData[hdr+5])[1]))-1)&0xffff)+1)]; + if( pData<pBegin ) goto editpage_fail; + + + if( iNew<iOld ){ + int nAdd = ((nNew)<(iOld-iNew)?(nNew):(iOld-iNew)); + assert( (iOld-iNew)<nNew || nCell==0 || (sqlite3Config.neverCorrupt==0) ); + assert( nAdd>=0 ); + pCellptr = pPg->aCellIdx; + memmove(&pCellptr[nAdd*2], pCellptr, nCell*2); + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iNew, nAdd, pCArray + ) ) goto editpage_fail; + nCell += nAdd; + } + + + for(i=0; i<pPg->nOverflow; i++){ + int iCell = (iOld + pPg->aiOvfl[i]) - iNew; + if( iCell>=0 && iCell<nNew ){ + pCellptr = &pPg->aCellIdx[iCell * 2]; + if( nCell>iCell ){ + memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); + } + nCell++; + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iCell+iNew, 1, pCArray + ) ) goto editpage_fail; + } + } + + + assert( nCell>=0 ); + pCellptr = &pPg->aCellIdx[nCell*2]; + if( pageInsertArray( + pPg, pBegin, &pData, pCellptr, + iNew+nCell, nNew-nCell, pCArray + ) ) goto editpage_fail; + + pPg->nCell = nNew; + pPg->nOverflow = 0; + + ((&aData[hdr+3])[0] = (u8)((pPg->nCell)>>8), (&aData[hdr+3])[1] = (u8)(pPg->nCell)); + ((&aData[hdr+5])[0] = (u8)((pData - aData)>>8), (&aData[hdr+5])[1] = (u8)(pData - aData)); +# 7190 "src/btree.c" + return 0; + editpage_fail: + + populateCellCache(pCArray, iNew, nNew); + return rebuildPage(pCArray, iNew, nNew, pPg); +} +# 7222 "src/btree.c" +static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ + BtShared *const pBt = pPage->pBt; + MemPage *pNew; + int rc; + Pgno pgnoNew; + + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + assert( pPage->nOverflow==1 ); + + if( pPage->nCell==0 ) return sqlite3CorruptError(7232); + assert( pPage->nFree>=0 ); + assert( pParent->nFree>=0 ); + + + + + + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + + if( rc==0 ){ + + u8 *pOut = &pSpace[4]; + u8 *pCell = pPage->apOvfl[0]; + u16 szCell = pPage->xCellSize(pPage, pCell); + u8 *pStop; + CellArray b; + + assert( sqlite3PagerIswriteable(pNew->pDbPage) ); + assert( (sqlite3Config.neverCorrupt==0) || pPage->aData[0]==(0x01|0x04|0x08) ); + zeroPage(pNew, 0x01|0x04|0x08); + b.nCell = 1; + b.pRef = pPage; + b.apCell = &pCell; + b.szCell = &szCell; + b.apEnd[0] = pPage->aDataEnd; + b.ixNx[0] = 2; + rc = rebuildPage(&b, 0, 1, pNew); + if( (rc) ){ + releasePage(pNew); + return rc; + } + pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; +# 7275 "src/btree.c" + if( (pBt->autoVacuum) ){ + ptrmapPut(pBt, pgnoNew, 5, pParent->pgno, &rc); + if( szCell>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); + } + } +# 7295 "src/btree.c" + pCell = ((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(pPage->nCell-1)])))); + pStop = &pCell[9]; + while( (*(pCell++)&0x80) && pCell<pStop ); + pStop = &pCell[9]; + while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop ); + + + if( rc==0 ){ + insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno, &rc); + } + + + sqlite3Put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); + + + releasePage(pNew); + } + + return rc; +} +# 7377 "src/btree.c" +static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ + if( (*pRC)==0 ){ + BtShared * const pBt = pFrom->pBt; + u8 * const aFrom = pFrom->aData; + u8 * const aTo = pTo->aData; + int const iFromHdr = pFrom->hdrOffset; + int const iToHdr = ((pTo->pgno==1) ? 100 : 0); + int rc; + int iData; + + + assert( pFrom->isInit ); + assert( pFrom->nFree>=iToHdr ); + assert( ((&aFrom[iFromHdr+5])[0]<<8 | (&aFrom[iFromHdr+5])[1]) <= (int)pBt->usableSize ); + + + iData = ((&aFrom[iFromHdr+5])[0]<<8 | (&aFrom[iFromHdr+5])[1]); + memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); + memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); + + + + + + + pTo->isInit = 0; + rc = btreeInitPage(pTo); + if( rc==0 ) rc = btreeComputeFreeSpace(pTo); + if( rc!=0 ){ + *pRC = rc; + return; + } + + + + + if( (pBt->autoVacuum) ){ + *pRC = setChildPtrmaps(pTo); + } + } +} +# 7459 "src/btree.c" +static int balance_nonroot( + MemPage *pParent, + int iParentIdx, + u8 *aOvflSpace, + int isRoot, + int bBulk +){ + BtShared *pBt; + int nMaxCells = 0; + int nNew = 0; + int nOld; + int i, j, k; + int nxDiv; + int rc = 0; + u16 leafCorrection; + int leafData; + int usableSpace; + int pageFlags; + int iSpace1 = 0; + int iOvflSpace = 0; + int szScratch; + MemPage *apOld[3]; + MemPage *apNew[3 +2]; + u8 *pRight; + u8 *apDiv[3 -1]; + int cntNew[3 +2]; + int cntOld[3 +2]; + int szNew[3 +2]; + u8 *aSpace1; + Pgno pgno; + u8 abDone[3 +2]; + Pgno aPgno[3 +2]; + Pgno aPgOrder[3 +2]; + u16 aPgFlags[3 +2]; + CellArray b; + + memset(abDone, 0, sizeof(abDone)); + b.nCell = 0; + b.apCell = 0; + pBt = pParent->pBt; + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + + + + + + + assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); + assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx ); + + if( !aOvflSpace ){ + return 7; + } + assert( pParent->nFree>=0 ); +# 7526 "src/btree.c" + i = pParent->nOverflow + pParent->nCell; + if( i<2 ){ + nxDiv = 0; + }else{ + assert( bBulk==0 || bBulk==1 ); + if( iParentIdx==0 ){ + nxDiv = 0; + }else if( iParentIdx==i ){ + nxDiv = i-2+bBulk; + }else{ + nxDiv = iParentIdx-1; + } + i = 2-bBulk; + } + nOld = i+1; + if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ + pRight = &pParent->aData[pParent->hdrOffset+8]; + }else{ + pRight = ((pParent)->aData + ((pParent)->maskPage & __builtin_bswap16(*(u16*)(&(pParent)->aCellIdx[2*(i+nxDiv-pParent->nOverflow)])))); + } + pgno = sqlite3Get4byte(pRight); + while( 1 ){ + rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + if( rc ){ + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + } + if( apOld[i]->nFree<0 ){ + rc = btreeComputeFreeSpace(apOld[i]); + if( rc ){ + memset(apOld, 0, (i)*sizeof(MemPage*)); + goto balance_cleanup; + } + } + if( (i--)==0 ) break; + + if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){ + apDiv[i] = pParent->apOvfl[0]; + pgno = sqlite3Get4byte(apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); + pParent->nOverflow = 0; + }else{ + apDiv[i] = ((pParent)->aData + ((pParent)->maskPage & __builtin_bswap16(*(u16*)(&(pParent)->aCellIdx[2*(i+nxDiv-pParent->nOverflow)])))); + pgno = sqlite3Get4byte(apDiv[i]); + szNew[i] = pParent->xCellSize(pParent, apDiv[i]); +# 7584 "src/btree.c" + if( pBt->btsFlags & 0x000c ){ + int iOff; + + iOff = ((int)(long int)(apDiv[i])) - ((int)(long int)(pParent->aData)); + if( (iOff+szNew[i])>(int)pBt->usableSize ){ + rc = sqlite3CorruptError(7589); + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; + }else{ + memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); + apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; + } + } + dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); + } + } + + + + nMaxCells = nOld*(((pBt->pageSize-8)/6) + ((int)(sizeof(pParent->apOvfl)/sizeof(pParent->apOvfl[0])))); + nMaxCells = (nMaxCells + 3)&~3; + + + + + szScratch = + nMaxCells*sizeof(u8*) + + nMaxCells*sizeof(u16) + + pBt->pageSize; + + assert( szScratch<=7*(int)pBt->pageSize ); + b.apCell = sqlite3DbMallocRaw(0,szScratch); + if( b.apCell==0 ){ + rc = 7; + goto balance_cleanup; + } + b.szCell = (u16*)&b.apCell[nMaxCells]; + aSpace1 = (u8*)&b.szCell[nMaxCells]; + assert( ((((char*)(aSpace1) - (char*)0)&7)==0) ); +# 7640 "src/btree.c" + b.pRef = apOld[0]; + leafCorrection = b.pRef->leaf*4; + leafData = b.pRef->intKeyLeaf; + for(i=0; i<nOld; i++){ + MemPage *pOld = apOld[i]; + int limit = pOld->nCell; + u8 *aData = pOld->aData; + u16 maskPage = pOld->maskPage; + u8 *piCell = aData + pOld->cellOffset; + u8 *piEnd; + + + + + + if( pOld->aData[0]!=apOld[0]->aData[0] ){ + rc = sqlite3CorruptError(7656); + goto balance_cleanup; + } +# 7677 "src/btree.c" + memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); + if( pOld->nOverflow>0 ){ + if( limit<pOld->aiOvfl[0] ){ + rc = sqlite3CorruptError(7680); + goto balance_cleanup; + } + limit = pOld->aiOvfl[0]; + for(j=0; j<limit; j++){ + b.apCell[b.nCell] = aData + (maskPage & __builtin_bswap16(*(u16*)(piCell))); + piCell += 2; + b.nCell++; + } + for(k=0; k<pOld->nOverflow; k++){ + assert( k==0 || pOld->aiOvfl[k-1]+1==pOld->aiOvfl[k] ); + b.apCell[b.nCell] = pOld->apOvfl[k]; + b.nCell++; + } + } + piEnd = aData + pOld->cellOffset + 2*pOld->nCell; + while( piCell<piEnd ){ + assert( b.nCell<nMaxCells ); + b.apCell[b.nCell] = aData + (maskPage & __builtin_bswap16(*(u16*)(piCell))); + piCell += 2; + b.nCell++; + } + assert( (b.nCell-nCellAtStart)==(pOld->nCell+pOld->nOverflow) ); + + cntOld[i] = b.nCell; + if( i<nOld-1 && !leafData){ + u16 sz = (u16)szNew[i]; + u8 *pTemp; + assert( b.nCell<nMaxCells ); + b.szCell[b.nCell] = sz; + pTemp = &aSpace1[iSpace1]; + iSpace1 += sz; + assert( sz<=pBt->maxLocal+23 ); + assert( iSpace1 <= (int)pBt->pageSize ); + memcpy(pTemp, apDiv[i], sz); + b.apCell[b.nCell] = pTemp+leafCorrection; + assert( leafCorrection==0 || leafCorrection==4 ); + b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection; + if( !pOld->leaf ){ + assert( leafCorrection==0 ); + assert( pOld->hdrOffset==0 ); + + + memcpy(b.apCell[b.nCell], &pOld->aData[8], 4); + }else{ + assert( leafCorrection==4 ); + while( b.szCell[b.nCell]<4 ){ + + + assert( b.szCell[b.nCell]==3 || (sqlite3Config.neverCorrupt==0) ); + assert( b.apCell[b.nCell]==&aSpace1[iSpace1-3] || (sqlite3Config.neverCorrupt==0) ); + aSpace1[iSpace1++] = 0x00; + b.szCell[b.nCell]++; + } + } + b.nCell++; + } + } +# 7755 "src/btree.c" + usableSpace = pBt->usableSize - 12 + leafCorrection; + for(i=k=0; i<nOld; i++, k++){ + MemPage *p = apOld[i]; + b.apEnd[k] = p->aDataEnd; + b.ixNx[k] = cntOld[i]; + if( k && b.ixNx[k]==b.ixNx[k-1] ){ + k--; + } + if( !leafData ){ + k++; + b.apEnd[k] = pParent->aDataEnd; + b.ixNx[k] = cntOld[i]+1; + } + assert( p->nFree>=0 ); + szNew[i] = usableSpace - p->nFree; + for(j=0; j<p->nOverflow; j++){ + szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]); + } + cntNew[i] = cntOld[i]; + } + k = nOld; + for(i=0; i<k; i++){ + int sz; + while( szNew[i]>usableSpace ){ + if( i+1>=k ){ + k = i+2; + if( k>3 +2 ){ rc = sqlite3CorruptError(7781); goto balance_cleanup; } + szNew[k-1] = 0; + cntNew[k-1] = b.nCell; + } + sz = 2 + cachedCellSize(&b, cntNew[i]-1); + szNew[i] -= sz; + if( !leafData ){ + if( cntNew[i]<b.nCell ){ + sz = 2 + cachedCellSize(&b, cntNew[i]); + }else{ + sz = 0; + } + } + szNew[i+1] += sz; + cntNew[i]--; + } + while( cntNew[i]<b.nCell ){ + sz = 2 + cachedCellSize(&b, cntNew[i]); + if( szNew[i]+sz>usableSpace ) break; + szNew[i] += sz; + cntNew[i]++; + if( !leafData ){ + if( cntNew[i]<b.nCell ){ + sz = 2 + cachedCellSize(&b, cntNew[i]); + }else{ + sz = 0; + } + } + szNew[i+1] -= sz; + } + if( cntNew[i]>=b.nCell ){ + k = i+1; + }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){ + rc = sqlite3CorruptError(7814); + goto balance_cleanup; + } + } +# 7830 "src/btree.c" + for(i=k-1; i>0; i--){ + int szRight = szNew[i]; + int szLeft = szNew[i-1]; + int r; + int d; + + r = cntNew[i-1] - 1; + d = r + 1 - leafData; + (void)cachedCellSize(&b, d); + do{ + assert( d<nMaxCells ); + assert( r<nMaxCells ); + (void)cachedCellSize(&b, r); + if( szRight!=0 + && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){ + break; + } + szRight += b.szCell[d] + 2; + szLeft -= b.szCell[r] + 2; + cntNew[i-1] = r; + r--; + d--; + }while( r>=0 ); + szNew[i] = szRight; + szNew[i-1] = szLeft; + if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){ + rc = sqlite3CorruptError(7856); + goto balance_cleanup; + } + } +# 7868 "src/btree.c" + assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || (sqlite3Config.neverCorrupt==0)); + + + + + ; + + + + + pageFlags = apOld[0]->aData[0]; + for(i=0; i<k; i++){ + MemPage *pNew; + if( i<nOld ){ + pNew = apNew[i] = apOld[i]; + apOld[i] = 0; + rc = sqlite3PagerWrite(pNew->pDbPage); + nNew++; + if( rc ) goto balance_cleanup; + }else{ + assert( i>0 ); + rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); + if( rc ) goto balance_cleanup; + zeroPage(pNew, pageFlags); + apNew[i] = pNew; + nNew++; + cntOld[i] = b.nCell; + + + if( (pBt->autoVacuum) ){ + ptrmapPut(pBt, pNew->pgno, 5, pParent->pgno, &rc); + if( rc!=0 ){ + goto balance_cleanup; + } + } + } + } +# 7918 "src/btree.c" + for(i=0; i<nNew; i++){ + aPgOrder[i] = aPgno[i] = apNew[i]->pgno; + aPgFlags[i] = apNew[i]->pDbPage->flags; + for(j=0; j<i; j++){ + if( aPgno[j]==aPgno[i] ){ + + + + + + + assert( (sqlite3Config.neverCorrupt==0) ); + rc = sqlite3CorruptError(7930); + goto balance_cleanup; + } + } + } + for(i=0; i<nNew; i++){ + int iBest = 0; + for(j=1; j<nNew; j++){ + if( aPgOrder[j]<aPgOrder[iBest] ) iBest = j; + } + pgno = aPgOrder[iBest]; + aPgOrder[iBest] = 0xffffffff; + if( iBest!=i ){ + if( iBest>i ){ + sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); + } + sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); + apNew[i]->pgno = pgno; + } + } + + +# 7962 "src/btree.c" + ; + + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + sqlite3Put4byte(pRight, apNew[nNew-1]->pgno); + + + + + if( (pageFlags & 0x08)==0 && nOld!=nNew ){ + MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1]; + memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4); + } +# 7991 "src/btree.c" + if( (pBt->autoVacuum) ){ + MemPage *pOld; + MemPage *pNew = pOld = apNew[0]; + int cntOldNext = pNew->nCell + pNew->nOverflow; + int iNew = 0; + int iOld = 0; + + for(i=0; i<b.nCell; i++){ + u8 *pCell = b.apCell[i]; + while( i==cntOldNext ){ + iOld++; + assert( iOld<nNew || iOld<nOld ); + assert( iOld>=0 && iOld<3 ); + pOld = iOld<nNew ? apNew[iOld] : apOld[iOld]; + cntOldNext += pOld->nCell + pOld->nOverflow + !leafData; + } + if( i==cntNew[iNew] ){ + pNew = apNew[++iNew]; + if( !leafData ) continue; + } + + + + + + + + if( iOld>=nNew + || pNew->pgno!=aPgno[iOld] + || !(((uptr)(pCell)>=(uptr)(pOld->aData))&&((uptr)(pCell)<(uptr)(pOld->aDataEnd))) + ){ + if( !leafCorrection ){ + ptrmapPut(pBt, sqlite3Get4byte(pCell), 5, pNew->pgno, &rc); + } + if( cachedCellSize(&b,i)>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pOld, pCell, &rc); + } + if( rc ) goto balance_cleanup; + } + } + } + + + for(i=0; i<nNew-1; i++){ + u8 *pCell; + u8 *pTemp; + int sz; + MemPage *pNew = apNew[i]; + j = cntNew[i]; + + assert( j<nMaxCells ); + assert( b.apCell[j]!=0 ); + pCell = b.apCell[j]; + sz = b.szCell[j] + leafCorrection; + pTemp = &aOvflSpace[iOvflSpace]; + if( !pNew->leaf ){ + memcpy(&pNew->aData[8], pCell, 4); + }else if( leafData ){ + + + + + + CellInfo info; + j--; + pNew->xParseCell(pNew, b.apCell[j], &info); + pCell = pTemp; + sz = 4 + sqlite3PutVarint(&pCell[4], info.nKey); + pTemp = 0; + }else{ + pCell -= 4; +# 8073 "src/btree.c" + if( b.szCell[j]==4 ){ + assert(leafCorrection==4); + sz = pParent->xCellSize(pParent, pCell); + } + } + iOvflSpace += sz; + assert( sz<=pBt->maxLocal+23 ); + assert( iOvflSpace <= (int)pBt->pageSize ); + insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); + if( rc!=0 ) goto balance_cleanup; + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + } +# 8108 "src/btree.c" + for(i=1-nNew; i<nNew; i++){ + int iPg = i<0 ? -i : i; + assert( iPg>=0 && iPg<nNew ); + if( abDone[iPg] ) continue; + if( i>=0 + || cntOld[iPg-1]>=cntNew[iPg-1] + ){ + int iNew; + int iOld; + int nNewCell; + + + + assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] ); + + + + assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] ); + + if( iPg==0 ){ + iNew = iOld = 0; + nNewCell = cntNew[0]; + }else{ + iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : b.nCell; + iNew = cntNew[iPg-1] + !leafData; + nNewCell = cntNew[iPg] - iNew; + } + + rc = editPage(apNew[iPg], iOld, iNew, nNewCell, &b); + if( rc ) goto balance_cleanup; + abDone[iPg]++; + apNew[iPg]->nFree = usableSpace-szNew[iPg]; + assert( apNew[iPg]->nOverflow==0 ); + assert( apNew[iPg]->nCell==nNewCell ); + } + } + + + assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 ); + + assert( nOld>0 ); + assert( nNew>0 ); + + if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ +# 8167 "src/btree.c" + assert( nNew==1 || (sqlite3Config.neverCorrupt==0) ); + rc = defragmentPage(apNew[0], -1); + ; + assert( apNew[0]->nFree == + ((((((int)((&apNew[0]->aData[5])[0]<<8 | (&apNew[0]->aData[5])[1]))-1)&0xffff)+1) - apNew[0]->cellOffset + - apNew[0]->nCell*2) + || rc!=0 + ); + copyNodeContent(apNew[0], pParent, &rc); + freePage(apNew[0], &rc); + }else if( (pBt->autoVacuum) && !leafCorrection ){ + + + + for(i=0; i<nNew; i++){ + u32 key = sqlite3Get4byte(&apNew[i]->aData[8]); + ptrmapPut(pBt, key, 5, apNew[i]->pgno, &rc); + } + } + + assert( pParent->isInit ); + + ; + + + + for(i=nNew; i<nOld; i++){ + freePage(apOld[i], &rc); + } +# 8211 "src/btree.c" +balance_cleanup: + sqlite3DbFree(0,b.apCell); + for(i=0; i<nOld; i++){ + releasePage(apOld[i]); + } + for(i=0; i<nNew; i++){ + releasePage(apNew[i]); + } + + return rc; +} +# 8243 "src/btree.c" +static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ + int rc; + MemPage *pChild = 0; + Pgno pgnoChild = 0; + BtShared *pBt = pRoot->pBt; + + assert( pRoot->nOverflow>0 ); + assert( sqlite3_mutex_held(pBt->mutex) ); + + + + + + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc==0 ){ + rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); + copyNodeContent(pRoot, pChild, &rc); + if( (pBt->autoVacuum) ){ + ptrmapPut(pBt, pgnoChild, 5, pRoot->pgno, &rc); + } + } + if( rc ){ + *ppChild = 0; + releasePage(pChild); + return rc; + } + assert( sqlite3PagerIswriteable(pChild->pDbPage) ); + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( pChild->nCell==pRoot->nCell || (sqlite3Config.neverCorrupt==0) ); + + ; + + + memcpy(pChild->aiOvfl, pRoot->aiOvfl, + pRoot->nOverflow*sizeof(pRoot->aiOvfl[0])); + memcpy(pChild->apOvfl, pRoot->apOvfl, + pRoot->nOverflow*sizeof(pRoot->apOvfl[0])); + pChild->nOverflow = pRoot->nOverflow; + + + zeroPage(pRoot, pChild->aData[0] & ~0x08); + sqlite3Put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild); + + *ppChild = pChild; + return 0; +} +# 8300 "src/btree.c" +static int balance(BtCursor *pCur){ + int rc = 0; + const int nMin = pCur->pBt->usableSize * 2 / 3; + u8 aBalanceQuickSpace[13]; + u8 *pFree = 0; + + ; + ; + + do { + int iPage = pCur->iPage; + MemPage *pPage = pCur->pPage; + + if( (pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break; + if( iPage==0 ){ + if( pPage->nOverflow ){ + + + + + + assert( balance_deeper_called==0 ); + ; + rc = balance_deeper(pPage, &pCur->apPage[1]); + if( rc==0 ){ + pCur->iPage = 1; + pCur->ix = 0; + pCur->aiIdx[0] = 0; + pCur->apPage[0] = pPage; + pCur->pPage = pCur->apPage[1]; + assert( pCur->pPage->nOverflow ); + } + }else{ + break; + } + }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ + break; + }else{ + MemPage * const pParent = pCur->apPage[iPage-1]; + int const iIdx = pCur->aiIdx[iPage-1]; + + rc = sqlite3PagerWrite(pParent->pDbPage); + if( rc==0 && pParent->nFree<0 ){ + rc = btreeComputeFreeSpace(pParent); + } + if( rc==0 ){ + + if( pPage->intKeyLeaf + && pPage->nOverflow==1 + && pPage->aiOvfl[0]==pPage->nCell + && pParent->pgno!=1 + && pParent->nCell==iIdx + ){ +# 8366 "src/btree.c" + assert( balance_quick_called==0 ); + ; + rc = balance_quick(pParent, pPage, aBalanceQuickSpace); + }else + + { +# 8389 "src/btree.c" + u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, + pCur->hints&0x00000001); + if( pFree ){ + + + + + sqlite3PageFree(pFree); + } + + + + + pFree = pSpace; + } + } + + pPage->nOverflow = 0; + + + releasePage(pPage); + pCur->iPage--; + assert( pCur->iPage>=0 ); + pCur->pPage = pCur->apPage[pCur->iPage]; + } + }while( rc==0 ); + + if( pFree ){ + sqlite3PageFree(pFree); + } + return rc; +} + + + + +static int btreeOverwriteContent( + MemPage *pPage, + u8 *pDest, + const BtreePayload *pX, + int iOffset, + int iAmt +){ + int nData = pX->nData - iOffset; + if( nData<=0 ){ + + int i; + for(i=0; i<iAmt && pDest[i]==0; i++){} + if( i<iAmt ){ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + memset(pDest + i, 0, iAmt - i); + } + }else{ + if( nData<iAmt ){ + + + int rc = btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData, + iAmt-nData); + if( rc ) return rc; + iAmt = nData; + } + if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){ + int rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + + + + + memmove(pDest, ((u8*)pX->pData) + iOffset, iAmt); + } + } + return 0; +} + + + + + +static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ + int iOffset; + int nTotal = pX->nData + pX->nZero; + int rc; + MemPage *pPage = pCur->pPage; + BtShared *pBt; + Pgno ovflPgno; + u32 ovflPageSize; + + if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){ + return sqlite3CorruptError(8479); + } + + rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, + 0, pCur->info.nLocal); + if( rc ) return rc; + if( pCur->info.nLocal==nTotal ) return 0; + + + iOffset = pCur->info.nLocal; + assert( nTotal>=0 ); + assert( iOffset>=0 ); + ovflPgno = sqlite3Get4byte(pCur->info.pPayload + iOffset); + pBt = pPage->pBt; + ovflPageSize = pBt->usableSize - 4; + do{ + rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); + if( rc ) return rc; + if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){ + rc = sqlite3CorruptError(8498); + }else{ + if( iOffset+ovflPageSize<(u32)nTotal ){ + ovflPgno = sqlite3Get4byte(pPage->aData); + }else{ + ovflPageSize = nTotal - iOffset; + } + rc = btreeOverwriteContent(pPage, pPage->aData+4, pX, + iOffset, ovflPageSize); + } + sqlite3PagerUnref(pPage->pDbPage); + if( rc ) return rc; + iOffset += ovflPageSize; + }while( iOffset<nTotal ); + return 0; +} +# 8546 "src/btree.c" +int sqlite3BtreeInsert( + BtCursor *pCur, + const BtreePayload *pX, + int flags, + int seekResult +){ + int rc; + int loc = seekResult; + int szNew = 0; + int idx; + MemPage *pPage; + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + unsigned char *oldCell; + unsigned char *newCell = 0; + + assert( (flags & (0x02|0x08))==flags ); + + if( pCur->eState==4 ){ + assert( pCur->skipNext!=0 ); + return pCur->skipNext; + } + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & 0x01)!=0 + && pBt->inTransaction==2 + && (pBt->btsFlags & 0x0001)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + + + + + + assert( (pX->pKey==0)==(pCur->pKeyInfo==0) ); +# 8593 "src/btree.c" + if( pCur->curFlags & 0x20 ){ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + } + + if( pCur->pKeyInfo==0 ){ + assert( pX->pKey==0 ); + + + invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); +# 8620 "src/btree.c" + if( (pCur->curFlags&0x02)!=0 && pX->nKey==pCur->info.nKey ){ + + + assert( pX->nData>=0 && pX->nZero>=0 ); + if( pCur->info.nSize!=0 + && pCur->info.nPayload==(u32)pX->nData+pX->nZero + ){ + + return btreeOverwriteCell(pCur, pX); + } + assert( loc==0 ); + }else if( loc==0 ){ + + + + + rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); + if( rc ) return rc; + } + }else{ + + + + + + assert( (flags & 0x02)==0 || loc==0 ); + + + + + + + if( loc==0 && (flags & 0x02)==0 ){ + if( pX->nMem ){ + UnpackedRecord r; + r.pKeyInfo = pCur->pKeyInfo; + r.aMem = pX->aMem; + r.nField = pX->nMem; + r.default_rc = 0; + r.errCode = 0; + r.r1 = 0; + r.r2 = 0; + r.eqSeen = 0; + rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); + }else{ + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); + } + if( rc ) return rc; + } + + + + + + if( loc==0 ){ + getCellInfo(pCur); + if( pCur->info.nKey==pX->nKey ){ + BtreePayload x2; + x2.pData = pX->pKey; + x2.nData = pX->nKey; + x2.nZero = 0; + return btreeOverwriteCell(pCur, &x2); + } + } + + } + assert( pCur->eState==0 || (pCur->eState==1 && loc) ); + + pPage = pCur->pPage; + assert( pPage->intKey || pX->nKey>=0 ); + assert( pPage->leaf || !pPage->intKey ); + if( pPage->nFree<0 ){ + rc = btreeComputeFreeSpace(pPage); + if( rc ) return rc; + } + + + + ; + assert( pPage->isInit ); + newCell = pBt->pTmpSpace; + assert( newCell!=0 ); + rc = fillInCell(pPage, newCell, pX, &szNew); + if( rc ) goto end_insert; + assert( szNew==pPage->xCellSize(pPage, newCell) ); + assert( szNew <= ((int)(pBt->pageSize-8)) ); + idx = pCur->ix; + if( loc==0 ){ + CellInfo info; + assert( idx<pPage->nCell ); + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ){ + goto end_insert; + } + oldCell = ((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(idx)])))); + if( !pPage->leaf ){ + memcpy(newCell, oldCell, 4); + } + rc = clearCell(pPage, oldCell, &info); + if( info.nSize==szNew && info.nLocal==info.nPayload + && (!(pBt->autoVacuum) || szNew<pPage->minLocal) + ){ +# 8731 "src/btree.c" + assert( rc==0 ); + if( oldCell+szNew > pPage->aDataEnd ) return sqlite3CorruptError(8732); + memcpy(oldCell, newCell, szNew); + return 0; + } + dropCell(pPage, idx, info.nSize, &rc); + if( rc ) goto end_insert; + }else if( loc<0 && pPage->nCell>0 ){ + assert( pPage->leaf ); + idx = ++pCur->ix; + pCur->curFlags &= ~0x02; + }else{ + assert( pPage->leaf ); + } + insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); + assert( pPage->nOverflow==0 || rc==0 ); + assert( rc!=0 || pPage->nCell>0 || pPage->nOverflow>0 ); +# 8769 "src/btree.c" + pCur->info.nSize = 0; + if( pPage->nOverflow ){ + assert( rc==0 ); + pCur->curFlags &= ~(0x02); + rc = balance(pCur); + + + + + + pCur->pPage->nOverflow = 0; + pCur->eState = 1; + if( (flags & 0x02) && rc==0 ){ + btreeReleaseAllCursorPages(pCur); + if( pCur->pKeyInfo ){ + assert( pCur->pKey==0 ); + pCur->pKey = sqlite3Malloc( pX->nKey ); + if( pCur->pKey==0 ){ + rc = 7; + }else{ + memcpy(pCur->pKey, pX->pKey, pX->nKey); + } + } + pCur->eState = 3; + pCur->nKey = pX->nKey; + } + } + assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 ); + +end_insert: + return rc; +} +# 8819 "src/btree.c" +int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ + Btree *p = pCur->pBtree; + BtShared *pBt = p->pBt; + int rc; + MemPage *pPage; + unsigned char *pCell; + int iCellIdx; + int iCellDepth; + CellInfo info; + int bSkipnext = 0; + u8 bPreserve = flags & 0x02; + + assert( cursorOwnsBtShared(pCur) ); + assert( pBt->inTransaction==2 ); + assert( (pBt->btsFlags & 0x0001)==0 ); + assert( pCur->curFlags & 0x01 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + assert( !hasReadConflicts(p, pCur->pgnoRoot) ); + assert( (flags & ~(0x02 | 0x04))==0 ); + if( pCur->eState==3 ){ + rc = btreeRestoreCursorPosition(pCur); + if( rc ) return rc; + } + assert( pCur->eState==0 ); + + iCellDepth = pCur->iPage; + iCellIdx = pCur->ix; + pPage = pCur->pPage; + pCell = ((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(iCellIdx)])))); + if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return 11; +# 8859 "src/btree.c" + if( bPreserve ){ + if( !pPage->leaf + || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) + || pPage->nCell==1 + ){ + + + rc = saveCursorKey(pCur); + if( rc ) return rc; + }else{ + bSkipnext = 1; + } + } +# 8880 "src/btree.c" + if( !pPage->leaf ){ + rc = sqlite3BtreePrevious(pCur, 0); + assert( rc!=101 ); + if( rc ) return rc; + } + + + + if( pCur->curFlags & 0x20 ){ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + } + + + + if( pCur->pKeyInfo==0 ){ + invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0); + } + + + + + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; + rc = clearCell(pPage, pCell, &info); + dropCell(pPage, iCellIdx, info.nSize, &rc); + if( rc ) return rc; + + + + + + + if( !pPage->leaf ){ + MemPage *pLeaf = pCur->pPage; + int nCell; + Pgno n; + unsigned char *pTmp; + + if( pLeaf->nFree<0 ){ + rc = btreeComputeFreeSpace(pLeaf); + if( rc ) return rc; + } + if( iCellDepth<pCur->iPage-1 ){ + n = pCur->apPage[iCellDepth+1]->pgno; + }else{ + n = pCur->pPage->pgno; + } + pCell = ((pLeaf)->aData + ((pLeaf)->maskPage & __builtin_bswap16(*(u16*)(&(pLeaf)->aCellIdx[2*(pLeaf->nCell-1)])))); + if( pCell<&pLeaf->aData[4] ) return sqlite3CorruptError(8929); + nCell = pLeaf->xCellSize(pLeaf, pCell); + assert( ((int)(pBt->pageSize-8)) >= nCell ); + pTmp = pBt->pTmpSpace; + assert( pTmp!=0 ); + rc = sqlite3PagerWrite(pLeaf->pDbPage); + if( rc==0 ){ + insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); + } + dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); + if( rc ) return rc; + } +# 8957 "src/btree.c" + rc = balance(pCur); + if( rc==0 && pCur->iPage>iCellDepth ){ + releasePageNotNull(pCur->pPage); + pCur->iPage--; + while( pCur->iPage>iCellDepth ){ + releasePage(pCur->apPage[pCur->iPage--]); + } + pCur->pPage = pCur->apPage[pCur->iPage]; + rc = balance(pCur); + } + + if( rc==0 ){ + if( bSkipnext ){ + assert( bPreserve && (pCur->iPage==iCellDepth || (sqlite3Config.neverCorrupt==0)) ); + assert( pPage==pCur->pPage || (sqlite3Config.neverCorrupt==0) ); + assert( (pPage->nCell>0 || (sqlite3Config.neverCorrupt==0)) && iCellIdx<=pPage->nCell ); + pCur->eState = 2; + if( iCellIdx>=pPage->nCell ){ + pCur->skipNext = -1; + pCur->ix = pPage->nCell-1; + }else{ + pCur->skipNext = 1; + } + }else{ + rc = moveToRoot(pCur); + if( bPreserve ){ + btreeReleaseAllCursorPages(pCur); + pCur->eState = 3; + } + if( rc==16 ) rc = 0; + } + } + return rc; +} +# 9003 "src/btree.c" +static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ + BtShared *pBt = p->pBt; + MemPage *pRoot; + Pgno pgnoRoot; + int rc; + int ptfFlags; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( pBt->inTransaction==2 ); + assert( (pBt->btsFlags & 0x0001)==0 ); + + + + + + + + if( pBt->autoVacuum ){ + Pgno pgnoMove; + MemPage *pPageMove; + + + + + + + invalidateAllOverflowCache(pBt); + + + + + + sqlite3BtreeGetMeta(p, 4, &pgnoRoot); + pgnoRoot++; + + + + + while( pgnoRoot==ptrmapPageno(pBt, pgnoRoot) || + pgnoRoot==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ){ + pgnoRoot++; + } + assert( pgnoRoot>=3 || (sqlite3Config.neverCorrupt==0) ); + ; + + + + + + rc = allocateBtreePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1); + if( rc!=0 ){ + return rc; + } + + if( pgnoMove!=pgnoRoot ){ + + + + + + + u8 eType = 0; + Pgno iPtrPage = 0; + + + + + rc = saveAllCursors(pBt, 0, 0); + releasePage(pPageMove); + if( rc!=0 ){ + return rc; + } + + + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=0 ){ + return rc; + } + rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); + if( eType==1 || eType==2 ){ + rc = sqlite3CorruptError(9083); + } + if( rc!=0 ){ + releasePage(pRoot); + return rc; + } + assert( eType!=1 ); + assert( eType!=2 ); + rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0); + releasePage(pRoot); + + + if( rc!=0 ){ + return rc; + } + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); + if( rc!=0 ){ + return rc; + } + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc!=0 ){ + releasePage(pRoot); + return rc; + } + }else{ + pRoot = pPageMove; + } + + + ptrmapPut(pBt, pgnoRoot, 1, 0, &rc); + if( rc ){ + releasePage(pRoot); + return rc; + } + + + + + + assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); + rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); + if( (rc) ){ + releasePage(pRoot); + return rc; + } + + }else{ + rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ) return rc; + } + + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); + if( createTabFlags & 1 ){ + ptfFlags = 0x01 | 0x04 | 0x08; + }else{ + ptfFlags = 0x02 | 0x08; + } + zeroPage(pRoot, ptfFlags); + sqlite3PagerUnref(pRoot->pDbPage); + assert( (pBt->openFlags & 4)==0 || pgnoRoot==2 ); + *piTable = (int)pgnoRoot; + return 0; +} +int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeCreateTable(p, piTable, flags); + sqlite3BtreeLeave(p); + return rc; +} + + + + + +static int clearDatabasePage( + BtShared *pBt, + Pgno pgno, + int freePageFlag, + int *pnChange +){ + MemPage *pPage; + int rc; + unsigned char *pCell; + int i; + int hdr; + CellInfo info; + + assert( sqlite3_mutex_held(pBt->mutex) ); + if( pgno>btreePagecount(pBt) ){ + return sqlite3CorruptError(9173); + } + rc = getAndInitPage(pBt, pgno, &pPage, 0, 0); + if( rc ) return rc; + if( pPage->bBusy ){ + rc = sqlite3CorruptError(9178); + goto cleardatabasepage_out; + } + pPage->bBusy = 1; + hdr = pPage->hdrOffset; + for(i=0; i<pPage->nCell; i++){ + pCell = ((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(i)])))); + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, sqlite3Get4byte(pCell), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + } + rc = clearCell(pPage, pCell, &info); + if( rc ) goto cleardatabasepage_out; + } + if( !pPage->leaf ){ + rc = clearDatabasePage(pBt, sqlite3Get4byte(&pPage->aData[hdr+8]), 1, pnChange); + if( rc ) goto cleardatabasepage_out; + }else if( pnChange ){ + assert( pPage->intKey || (sqlite3Config.neverCorrupt==0) ); + ; + *pnChange += pPage->nCell; + } + if( freePageFlag ){ + freePage(pPage, &rc); + }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ + zeroPage(pPage, pPage->aData[hdr] | 0x08); + } + +cleardatabasepage_out: + pPage->bBusy = 0; + releasePage(pPage); + return rc; +} +# 9225 "src/btree.c" +int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ + int rc; + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + assert( p->inTrans==2 ); + + rc = saveAllCursors(pBt, (Pgno)iTable, 0); + + if( 0==rc ){ + + + + invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); + rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); + } + sqlite3BtreeLeave(p); + return rc; +} + + + + + + +int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){ + return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); +} +# 9273 "src/btree.c" +static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ + int rc; + MemPage *pPage = 0; + BtShared *pBt = p->pBt; + + assert( sqlite3BtreeHoldsMutex(p) ); + assert( p->inTrans==2 ); + assert( iTable>=2 ); + if( iTable>btreePagecount(pBt) ){ + return sqlite3CorruptError(9282); + } + + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); + if( rc ) return rc; + rc = sqlite3BtreeClearTable(p, iTable, 0); + if( rc ){ + releasePage(pPage); + return rc; + } + + *piMoved = 0; + + + + + + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + sqlite3BtreeGetMeta(p, 4, &maxRootPgno); + + if( iTable==maxRootPgno ){ + + + + freePage(pPage, &rc); + releasePage(pPage); + if( rc!=0 ){ + return rc; + } + }else{ + + + + + MemPage *pMove; + releasePage(pPage); + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + if( rc!=0 ){ + return rc; + } + rc = relocatePage(pBt, pMove, 1, 0, iTable, 0); + releasePage(pMove); + if( rc!=0 ){ + return rc; + } + pMove = 0; + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + freePage(pMove, &rc); + releasePage(pMove); + if( rc!=0 ){ + return rc; + } + *piMoved = maxRootPgno; + } + + + + + + + maxRootPgno--; + while( maxRootPgno==((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) + || (ptrmapPageno((pBt), (maxRootPgno))==(maxRootPgno)) ){ + maxRootPgno--; + } + assert( maxRootPgno!=((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)) ); + + rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); + }else{ + freePage(pPage, &rc); + releasePage(pPage); + } + + return rc; +} +int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ + int rc; + sqlite3BtreeEnter(p); + rc = btreeDropTable(p, iTable, piMoved); + sqlite3BtreeLeave(p); + return rc; +} +# 9387 "src/btree.c" +void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ + BtShared *pBt = p->pBt; + + sqlite3BtreeEnter(p); + assert( p->inTrans>0 ); + assert( 0==querySharedCacheTableLock(p, 1, 1) ); + assert( pBt->pPage1 ); + assert( idx>=0 && idx<=15 ); + + if( idx==15 ){ + *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; + }else{ + *pMeta = sqlite3Get4byte(&pBt->pPage1->aData[36 + idx*4]); + } +# 9410 "src/btree.c" + sqlite3BtreeLeave(p); +} + + + + + +int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ + BtShared *pBt = p->pBt; + unsigned char *pP1; + int rc; + assert( idx>=1 && idx<=15 ); + sqlite3BtreeEnter(p); + assert( p->inTrans==2 ); + assert( pBt->pPage1!=0 ); + pP1 = pBt->pPage1->aData; + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==0 ){ + sqlite3Put4byte(&pP1[36 + idx*4], iMeta); + + if( idx==7 ){ + assert( pBt->autoVacuum || iMeta==0 ); + assert( iMeta==0 || iMeta==1 ); + pBt->incrVacuum = (u8)iMeta; + } + + } + sqlite3BtreeLeave(p); + return rc; +} +# 9450 "src/btree.c" +int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ + i64 nEntry = 0; + int rc; + + rc = moveToRoot(pCur); + if( rc==16 ){ + *pnEntry = 0; + return 0; + } + + + + + while( rc==0 ){ + int iIdx; + MemPage *pPage; + + + + + + pPage = pCur->pPage; + if( pPage->leaf || !pPage->intKey ){ + nEntry += pPage->nCell; + } +# 9486 "src/btree.c" + if( pPage->leaf ){ + do { + if( pCur->iPage==0 ){ + + *pnEntry = nEntry; + return moveToRoot(pCur); + } + moveToParent(pCur); + }while ( pCur->ix>=pCur->pPage->nCell ); + + pCur->ix++; + pPage = pCur->pPage; + } + + + + + iIdx = pCur->ix; + if( iIdx==pPage->nCell ){ + rc = moveToChild(pCur, sqlite3Get4byte(&pPage->aData[pPage->hdrOffset+8])); + }else{ + rc = moveToChild(pCur, sqlite3Get4byte(((pPage)->aData + ((pPage)->maskPage & __builtin_bswap16(*(u16*)(&(pPage)->aCellIdx[2*(iIdx)])))))); + } + } + + + return rc; +} + + + + + + +Pager *sqlite3BtreePager(Btree *p){ + return p->pBt->pPager; +} + + + + + +static void checkAppendMsg( + IntegrityCk *pCheck, + const char *zFormat, + ... +){ + va_list ap; + if( !pCheck->mxErr ) return; + pCheck->mxErr--; + pCheck->nErr++; + __builtin_va_start((ap)); + if( pCheck->errMsg.nChar ){ + sqlite3_str_append(&pCheck->errMsg, "\n", 1); + } + if( pCheck->zPfx ){ + sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); + } + sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); + ; + if( pCheck->errMsg.accError==7 ){ + pCheck->mallocFailed = 1; + } +} +# 9558 "src/btree.c" +static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); +} + + + + +static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ + assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); +} +# 9580 "src/btree.c" +static int checkRef(IntegrityCk *pCheck, Pgno iPage){ + if( iPage>pCheck->nPage || iPage==0 ){ + checkAppendMsg(pCheck, "invalid page number %d", iPage); + return 1; + } + if( getPageReferenced(pCheck, iPage) ){ + checkAppendMsg(pCheck, "2nd reference to page %d", iPage); + return 1; + } + setPageReferenced(pCheck, iPage); + return 0; +} + + + + + + + +static void checkPtrmap( + IntegrityCk *pCheck, + Pgno iChild, + u8 eType, + Pgno iParent +){ + int rc; + u8 ePtrmapType; + Pgno iPtrmapParent; + + rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); + if( rc!=0 ){ + if( rc==7 || rc==(10 | (12<<8)) ) pCheck->mallocFailed = 1; + checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild); + return; + } + + if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ + checkAppendMsg(pCheck, + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", + iChild, eType, iParent, ePtrmapType, iPtrmapParent); + } +} + + + + + + +static void checkList( + IntegrityCk *pCheck, + int isFreeList, + int iPage, + u32 N +){ + int i; + u32 expected = N; + int nErrAtStart = pCheck->nErr; + while( iPage!=0 && pCheck->mxErr ){ + DbPage *pOvflPage; + unsigned char *pOvflData; + if( checkRef(pCheck, iPage) ) break; + N--; + if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ + checkAppendMsg(pCheck, "failed to get page %d", iPage); + break; + } + pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); + if( isFreeList ){ + u32 n = (u32)sqlite3Get4byte(&pOvflData[4]); + + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iPage, 2, 0); + } + + if( n>pCheck->pBt->usableSize/4-2 ){ + checkAppendMsg(pCheck, + "freelist leaf count too big on page %d", iPage); + N--; + }else{ + for(i=0; i<(int)n; i++){ + Pgno iFreePage = sqlite3Get4byte(&pOvflData[8+i*4]); + + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iFreePage, 2, 0); + } + + checkRef(pCheck, iFreePage); + } + N -= n; + } + } + + else{ + + + + + if( pCheck->pBt->autoVacuum && N>0 ){ + i = sqlite3Get4byte(pOvflData); + checkPtrmap(pCheck, i, 4, iPage); + } + } + + iPage = sqlite3Get4byte(pOvflData); + sqlite3PagerUnref(pOvflPage); + } + if( N && nErrAtStart==pCheck->nErr ){ + checkAppendMsg(pCheck, + "%s is %d but should be %d", + isFreeList ? "size" : "overflow list length", + expected-N, expected); + } +} +# 9717 "src/btree.c" +static void btreeHeapInsert(u32 *aHeap, u32 x){ + u32 j, i = ++aHeap[0]; + aHeap[i] = x; + while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){ + x = aHeap[j]; + aHeap[j] = aHeap[i]; + aHeap[i] = x; + i = j; + } +} +static int btreeHeapPull(u32 *aHeap, u32 *pOut){ + u32 j, i, x; + if( (x = aHeap[0])==0 ) return 0; + *pOut = aHeap[1]; + aHeap[1] = aHeap[x]; + aHeap[x] = 0xffffffff; + aHeap[0]--; + i = 1; + while( (j = i*2)<=aHeap[0] ){ + if( aHeap[j]>aHeap[j+1] ) j++; + if( aHeap[i]<aHeap[j] ) break; + x = aHeap[i]; + aHeap[i] = aHeap[j]; + aHeap[j] = x; + i = j; + } + return 1; +} +# 9761 "src/btree.c" +static int checkTreePage( + IntegrityCk *pCheck, + int iPage, + i64 *piMinKey, + i64 maxKey +){ + MemPage *pPage = 0; + int i; + int rc; + int depth = -1, d2; + int pgno; + int nFrag; + int hdr; + int cellStart; + int nCell; + int doCoverageCheck = 1; + int keyCanBeEqual = 1; + + u8 *data; + u8 *pCell; + u8 *pCellIdx; + BtShared *pBt; + u32 pc; + u32 usableSize; + u32 contentOffset; + u32 *heap = 0; + u32 x, prev = 0; + const char *saved_zPfx = pCheck->zPfx; + int saved_v1 = pCheck->v1; + int saved_v2 = pCheck->v2; + u8 savedIsInit = 0; + + + + pBt = pCheck->pBt; + usableSize = pBt->usableSize; + if( iPage==0 ) return 0; + if( checkRef(pCheck, iPage) ) return 0; + pCheck->zPfx = "Page %d: "; + pCheck->v1 = iPage; + if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ + checkAppendMsg(pCheck, + "unable to get the page. error code=%d", rc); + goto end_of_check; + } + + + + savedIsInit = pPage->isInit; + pPage->isInit = 0; + if( (rc = btreeInitPage(pPage))!=0 ){ + assert( rc==11 ); + checkAppendMsg(pCheck, + "btreeInitPage() returns error code %d", rc); + goto end_of_check; + } + if( (rc = btreeComputeFreeSpace(pPage))!=0 ){ + assert( rc==11 ); + checkAppendMsg(pCheck, "free space corruption", rc); + goto end_of_check; + } + data = pPage->aData; + hdr = pPage->hdrOffset; + + + pCheck->zPfx = "On tree page %d cell %d: "; + contentOffset = (((((int)((&data[hdr+5])[0]<<8 | (&data[hdr+5])[1]))-1)&0xffff)+1); + assert( contentOffset<=usableSize ); + + + + nCell = ((&data[hdr+3])[0]<<8 | (&data[hdr+3])[1]); + assert( pPage->nCell==nCell ); + + + + cellStart = hdr + 12 - 4*pPage->leaf; + assert( pPage->aCellIdx==&data[cellStart] ); + pCellIdx = &data[cellStart + 2*(nCell-1)]; + + if( !pPage->leaf ){ + + pgno = sqlite3Get4byte(&data[hdr+8]); + + if( pBt->autoVacuum ){ + pCheck->zPfx = "On page %d at right child: "; + checkPtrmap(pCheck, pgno, 5, iPage); + } + + depth = checkTreePage(pCheck, pgno, &maxKey, maxKey); + keyCanBeEqual = 0; + }else{ + + + heap = pCheck->heap; + heap[0] = 0; + } + + + + for(i=nCell-1; i>=0 && pCheck->mxErr; i--){ + CellInfo info; + + + pCheck->v2 = i; + assert( pCellIdx==&data[cellStart + i*2] ); + pc = __builtin_bswap16(*(u16*)(pCellIdx)); + pCellIdx -= 2; + if( pc<contentOffset || pc>usableSize-4 ){ + checkAppendMsg(pCheck, "Offset %d out of range %d..%d", + pc, contentOffset, usableSize-4); + doCoverageCheck = 0; + continue; + } + pCell = &data[pc]; + pPage->xParseCell(pPage, pCell, &info); + if( pc+info.nSize>usableSize ){ + checkAppendMsg(pCheck, "Extends off end of page"); + doCoverageCheck = 0; + continue; + } + + + if( pPage->intKey ){ + if( keyCanBeEqual ? (info.nKey > maxKey) : (info.nKey >= maxKey) ){ + checkAppendMsg(pCheck, "Rowid %lld out of order", info.nKey); + } + maxKey = info.nKey; + keyCanBeEqual = 0; + } + + + if( info.nPayload>info.nLocal ){ + u32 nPage; + Pgno pgnoOvfl; + assert( pc + info.nSize - 4 <= usableSize ); + nPage = (info.nPayload - info.nLocal + usableSize - 5)/(usableSize - 4); + pgnoOvfl = sqlite3Get4byte(&pCell[info.nSize - 4]); + + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgnoOvfl, 3, iPage); + } + + checkList(pCheck, 0, pgnoOvfl, nPage); + } + + if( !pPage->leaf ){ + + pgno = sqlite3Get4byte(pCell); + + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, 5, iPage); + } + + d2 = checkTreePage(pCheck, pgno, &maxKey, maxKey); + keyCanBeEqual = 0; + if( d2!=depth ){ + checkAppendMsg(pCheck, "Child page depth differs"); + depth = d2; + } + }else{ + + btreeHeapInsert(heap, (pc<<16)|(pc+info.nSize-1)); + } + } + *piMinKey = maxKey; + + + + pCheck->zPfx = 0; + if( doCoverageCheck && pCheck->mxErr>0 ){ + + + + if( !pPage->leaf ){ + heap = pCheck->heap; + heap[0] = 0; + for(i=nCell-1; i>=0; i--){ + u32 size; + pc = __builtin_bswap16(*(u16*)(&data[cellStart+i*2])); + size = pPage->xCellSize(pPage, &data[pc]); + btreeHeapInsert(heap, (pc<<16)|(pc+size-1)); + } + } + + + + + + + i = ((&data[hdr+1])[0]<<8 | (&data[hdr+1])[1]); + while( i>0 ){ + int size, j; + assert( (u32)i<=usableSize-4 ); + size = ((&data[i+2])[0]<<8 | (&data[i+2])[1]); + assert( (u32)(i+size)<=usableSize ); + btreeHeapInsert(heap, (((u32)i)<<16)|(i+size-1)); + + + + + j = ((&data[i])[0]<<8 | (&data[i])[1]); + + + assert( j==0 || j>i+size ); + assert( (u32)j<=usableSize-4 ); + i = j; + } +# 9982 "src/btree.c" + nFrag = 0; + prev = contentOffset - 1; + while( btreeHeapPull(heap,&x) ){ + if( (prev&0xffff)>=(x>>16) ){ + checkAppendMsg(pCheck, + "Multiple uses for byte %u of page %d", x>>16, iPage); + break; + }else{ + nFrag += (x>>16) - (prev&0xffff) - 1; + prev = x; + } + } + nFrag += usableSize - (prev&0xffff) - 1; + + + + + + if( heap[0]==0 && nFrag!=data[hdr+7] ){ + checkAppendMsg(pCheck, + "Fragmentation of %d bytes reported as %d on page %d", + nFrag, data[hdr+7], iPage); + } + } + +end_of_check: + if( !doCoverageCheck ) pPage->isInit = savedIsInit; + releasePage(pPage); + pCheck->zPfx = saved_zPfx; + pCheck->v1 = saved_v1; + pCheck->v2 = saved_v2; + return depth+1; +} +# 10031 "src/btree.c" +char *sqlite3BtreeIntegrityCheck( + Btree *p, + int *aRoot, + int nRoot, + int mxErr, + int *pnErr +){ + Pgno i; + IntegrityCk sCheck; + BtShared *pBt = p->pBt; + u64 savedDbFlags = pBt->db->flags; + char zErr[100]; + ; + + sqlite3BtreeEnter(p); + assert( p->inTrans>0 && pBt->inTransaction>0 ); + ; + assert( nRef>=0 ); + sCheck.pBt = pBt; + sCheck.pPager = pBt->pPager; + sCheck.nPage = btreePagecount(sCheck.pBt); + sCheck.mxErr = mxErr; + sCheck.nErr = 0; + sCheck.mallocFailed = 0; + sCheck.zPfx = 0; + sCheck.v1 = 0; + sCheck.v2 = 0; + sCheck.aPgRef = 0; + sCheck.heap = 0; + sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), 1000000000); + sCheck.errMsg.printfFlags = 0x01; + if( sCheck.nPage==0 ){ + goto integrity_ck_cleanup; + } + + sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); + if( !sCheck.aPgRef ){ + sCheck.mallocFailed = 1; + goto integrity_ck_cleanup; + } + sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); + if( sCheck.heap==0 ){ + sCheck.mallocFailed = 1; + goto integrity_ck_cleanup; + } + + i = ((Pgno)((sqlite3PendingByte/((pBt)->pageSize))+1)); + if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); + + + + sCheck.zPfx = "Main freelist: "; + checkList(&sCheck, 1, sqlite3Get4byte(&pBt->pPage1->aData[32]), + sqlite3Get4byte(&pBt->pPage1->aData[36])); + sCheck.zPfx = 0; + + + + + if( pBt->autoVacuum ){ + int mx = 0; + int mxInHdr; + for(i=0; (int)i<nRoot; i++) if( mx<aRoot[i] ) mx = aRoot[i]; + mxInHdr = sqlite3Get4byte(&pBt->pPage1->aData[52]); + if( mx!=mxInHdr ){ + checkAppendMsg(&sCheck, + "max rootpage (%d) disagrees with header (%d)", + mx, mxInHdr + ); + } + }else if( sqlite3Get4byte(&pBt->pPage1->aData[64])!=0 ){ + checkAppendMsg(&sCheck, + "incremental_vacuum enabled with a max rootpage of zero" + ); + } + + ; + pBt->db->flags &= ~(u64)0x00200000; + for(i=0; (int)i<nRoot && sCheck.mxErr; i++){ + i64 notUsed; + if( aRoot[i]==0 ) continue; + + if( pBt->autoVacuum && aRoot[i]>1 ){ + checkPtrmap(&sCheck, aRoot[i], 1, 0); + } + + checkTreePage(&sCheck, aRoot[i], ¬Used, (0xffffffff|(((i64)0x7fffffff)<<32))); + } + pBt->db->flags = savedDbFlags; + + + + for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ +# 10132 "src/btree.c" + if( getPageReferenced(&sCheck, i)==0 && + (ptrmapPageno(pBt, i)!=i || !pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Page %d is never used", i); + } + if( getPageReferenced(&sCheck, i)!=0 && + (ptrmapPageno(pBt, i)==i && pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i); + } + + } + + + +integrity_ck_cleanup: + sqlite3PageFree(sCheck.heap); + sqlite3_free(sCheck.aPgRef); + if( sCheck.mallocFailed ){ + sqlite3_str_reset(&sCheck.errMsg); + sCheck.nErr++; + } + *pnErr = sCheck.nErr; + if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg); + + assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); + sqlite3BtreeLeave(p); + return sqlite3StrAccumFinish(&sCheck.errMsg); +} +# 10168 "src/btree.c" +const char *sqlite3BtreeGetFilename(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerFilename(p->pBt->pPager, 1); +} +# 10181 "src/btree.c" +const char *sqlite3BtreeGetJournalname(Btree *p){ + assert( p->pBt->pPager!=0 ); + return sqlite3PagerJournalname(p->pBt->pPager); +} + + + + +int sqlite3BtreeIsInTrans(Btree *p){ + assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); + return (p && (p->inTrans==2)); +} +# 10203 "src/btree.c" +int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ + int rc = 0; + if( p ){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( pBt->inTransaction!=0 ){ + rc = 6; + }else{ + rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt); + } + sqlite3BtreeLeave(p); + } + return rc; +} + + + + + +int sqlite3BtreeIsInReadTrans(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->inTrans!=0; +} + +int sqlite3BtreeIsInBackup(Btree *p){ + assert( p ); + assert( sqlite3_mutex_held(p->db->mutex) ); + return p->nBackup!=0; +} +# 10254 "src/btree.c" +void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ + BtShared *pBt = p->pBt; + sqlite3BtreeEnter(p); + if( !pBt->pSchema && nBytes ){ + pBt->pSchema = sqlite3DbMallocZero(0, nBytes); + pBt->xFreeSchema = xFree; + } + sqlite3BtreeLeave(p); + return pBt->pSchema; +} + + + + + + +int sqlite3BtreeSchemaLocked(Btree *p){ + int rc; + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, 1, 1); + assert( rc==0 || rc==(6 | (1<<8)) ); + sqlite3BtreeLeave(p); + return rc; +} +# 10287 "src/btree.c" +int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ + int rc = 0; + assert( p->inTrans!=0 ); + if( p->sharable ){ + u8 lockType = 1 + isWriteLock; + assert( 1 +1==2 ); + assert( isWriteLock==0 || isWriteLock==1 ); + + sqlite3BtreeEnter(p); + rc = querySharedCacheTableLock(p, iTab, lockType); + if( rc==0 ){ + rc = setSharedCacheTableLock(p, iTab, lockType); + } + sqlite3BtreeLeave(p); + } + return rc; +} +# 10317 "src/btree.c" +int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ + int rc; + assert( cursorOwnsBtShared(pCsr) ); + assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); + assert( pCsr->curFlags & 0x10 ); + + rc = (pCsr->eState>=3 ? btreeRestoreCursorPosition(pCsr) : 0); + if( rc!=0 ){ + return rc; + } + assert( pCsr->eState!=3 ); + if( pCsr->eState!=0 ){ + return 4; + } +# 10340 "src/btree.c" + saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr); + assert( rc==0 ); +# 10350 "src/btree.c" + if( (pCsr->curFlags & 0x01)==0 ){ + return 8; + } + assert( (pCsr->pBt->btsFlags & 0x0001)==0 + && pCsr->pBt->inTransaction==2 ); + assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); + assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); + assert( pCsr->pPage->intKey ); + + return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); +} + + + + +void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ + pCur->curFlags |= 0x10; + pCur->pBtree->hasIncrblobCur = 1; +} + + + + + + + +int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ + BtShared *pBt = pBtree->pBt; + int rc; + + assert( iVersion==1 || iVersion==2 ); + + + + + pBt->btsFlags &= ~0x0020; + if( iVersion==1 ) pBt->btsFlags |= 0x0020; + + rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); + if( rc==0 ){ + u8 *aData = pBt->pPage1->aData; + if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ + rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); + if( rc==0 ){ + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); + if( rc==0 ){ + aData[18] = (u8)iVersion; + aData[19] = (u8)iVersion; + } + } + } + } + + pBt->btsFlags &= ~0x0020; + return rc; +} + + + + + +int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ + return (pCsr->hints & mask)!=0; +} + + + + +int sqlite3BtreeIsReadonly(Btree *p){ + return (p->pBt->btsFlags & 0x0001)!=0; +} + + + + +int sqlite3HeaderSizeBtree(void){ return (((sizeof(MemPage))+7)&~7); } + + + + + +int sqlite3BtreeSharable(Btree *p){ + return p->sharable; +} + + + + + + +int sqlite3BtreeConnectionCount(Btree *p){ + ; + return p->pBt->nRef; +} |