amalgalite 1.0.0-x86-mingw32 → 1.1.1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.rdoc +16 -0
- data/bin/amalgalite-pack +29 -8
- data/examples/fts3.db +0 -0
- data/examples/fts3.rb +144 -0
- data/ext/amalgalite/amalgalite3_constants.c +32 -32
- data/ext/amalgalite/extconf.rb +3 -0
- data/ext/amalgalite/gen_constants.rb +5 -1
- data/ext/amalgalite/sqlite3.c +815 -460
- data/ext/amalgalite/sqlite3.h +118 -45
- data/gemspec.rb +5 -5
- data/lib/amalgalite/1.8/amalgalite3.so +0 -0
- data/lib/amalgalite/1.9/amalgalite3.so +0 -0
- data/lib/amalgalite/version.rb +2 -2
- data/spec/sqlite3/version_spec.rb +5 -5
- data/tasks/announce.rake +1 -0
- data/tasks/extension.rake +3 -1
- metadata +15 -13
data/HISTORY.rdoc
CHANGED
@@ -1,4 +1,20 @@
|
|
1
1
|
= Amalgalite Changelog
|
2
|
+
== Version 1.1.1 - 2011-03-27
|
3
|
+
|
4
|
+
=== Enhancements
|
5
|
+
|
6
|
+
* Update to SQLite 3.7.5
|
7
|
+
* Enable SQLite Full Text Search compile time options FTS3 and FTS4 [github issue #10]
|
8
|
+
http://www.sqlite.org/fts3.html
|
9
|
+
* Enable STAT2 SQLite compile time option to improve ANALYZE command support
|
10
|
+
http://www.sqlite.org/lang_analyze.html
|
11
|
+
|
12
|
+
=== Bug Fixes
|
13
|
+
|
14
|
+
* The C coded generated by gen_constants.rb was updated to support older
|
15
|
+
compilers [github issue #8] (patch from josb)
|
16
|
+
* Fix 'amalgalite-pack --self' on ruby 1.9
|
17
|
+
|
2
18
|
== Version 1.0.0 - 2011-01-16
|
3
19
|
|
4
20
|
=== Enhancements
|
data/bin/amalgalite-pack
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'optparse'
|
3
3
|
require 'pathname'
|
4
|
-
require 'rubygems'
|
5
4
|
|
6
5
|
#
|
7
6
|
# add relative paths to the load path if we are not a gem and calculate what the
|
@@ -16,14 +15,36 @@ if ".." == rel_path.to_s.split( File::SEPARATOR ).first then
|
|
16
15
|
$:.unshift File.join( File.dirname( __FILE__ ), "../ext" )
|
17
16
|
end
|
18
17
|
|
19
|
-
#
|
18
|
+
#
|
20
19
|
# snapshot of what is needed for amalgalite requires, this info may only be used
|
21
20
|
# when packing amalgalite itself
|
22
21
|
#
|
23
22
|
loaded_features_before = $LOADED_FEATURES.dup
|
24
23
|
require 'amalgalite/packer'
|
25
24
|
loaded_features_after = $LOADED_FEATURES.dup
|
26
|
-
|
25
|
+
load_diff = loaded_features_after - loaded_features_before
|
26
|
+
|
27
|
+
#
|
28
|
+
# strip off any LOAD_PATH elements from the front of load_diff since that
|
29
|
+
# will conflict with Amalgalite::Packer.amalgalite_require_order. Also
|
30
|
+
# strip out any 'rubygems' items since those are not used by Amalgalite
|
31
|
+
# and show as a side effect fo the "require 'amalgalite/packer'"
|
32
|
+
#
|
33
|
+
strip_paths = $LOAD_PATH.sort.reverse
|
34
|
+
amalgalite_needs = []
|
35
|
+
load_diff.each do |f|
|
36
|
+
next if f.split( File::SEPARATOR ).include?( "rubygems" )
|
37
|
+
appended = false
|
38
|
+
strip_paths.each do |path|
|
39
|
+
if 0 == f.index(path ) then
|
40
|
+
rel_path = f.sub( path, '' ).sub(%r{\A#{File::SEPARATOR}},'')
|
41
|
+
amalgalite_needs << rel_path
|
42
|
+
appended = true
|
43
|
+
break
|
44
|
+
end
|
45
|
+
end
|
46
|
+
amalgalite_needs << f unless appended
|
47
|
+
end
|
27
48
|
|
28
49
|
#
|
29
50
|
# Commandline parser
|
@@ -77,7 +98,7 @@ begin
|
|
77
98
|
require 'amalgalite/packer'
|
78
99
|
file_list = ARGV.dup
|
79
100
|
|
80
|
-
|
101
|
+
|
81
102
|
if options[:self] then
|
82
103
|
options[:table_name] = Amalgalite::Requires::Bootstrap::DEFAULT_BOOTSTRAP_TABLE
|
83
104
|
core_libs = (amalgalite_needs - Amalgalite::Packer.amalgalite_require_order).delete_if { |l| l.index(".rb").nil? }
|
@@ -85,9 +106,9 @@ begin
|
|
85
106
|
#
|
86
107
|
# check and make sure nothing is missed
|
87
108
|
#
|
88
|
-
core_libs.each do |l|
|
89
|
-
if l.index("
|
90
|
-
STDERR.puts "ERROR! require_order needs an update #{l}"
|
109
|
+
core_libs.each do |l|
|
110
|
+
if l.index("amalgalite") then
|
111
|
+
STDERR.puts "ERROR! require_order needs an update #{l}"
|
91
112
|
exit 2
|
92
113
|
end
|
93
114
|
end
|
@@ -116,7 +137,7 @@ Packing complete. To utilize the bootstrapping in #{dbfile} you must do
|
|
116
137
|
one of the following:
|
117
138
|
|
118
139
|
* statically compile the amalgalite C extension into your application
|
119
|
-
* require 'amalgalite/amalgalite3'
|
140
|
+
* require 'amalgalite/#{RUBY_VERSION.sub(/\.\d$/,'')}/amalgalite3'
|
120
141
|
|
121
142
|
Once one of those is working you can boostrap the Amalgalite library with
|
122
143
|
this line in your code:
|
data/examples/fts3.db
ADDED
Binary file
|
data/examples/fts3.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'amalgalite'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'json'
|
8
|
+
rescue LoadError
|
9
|
+
abort "'gem install json' to run this example"
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
README = <<_
|
14
|
+
This example programs assumes that you have downloaded the 'Tweets During the
|
15
|
+
State of the Union address' dataset from infochimps.com
|
16
|
+
|
17
|
+
http://www.infochimps.com/datasets/tweets-during-state-of-the-union-address
|
18
|
+
|
19
|
+
Please:
|
20
|
+
1) download this dataset
|
21
|
+
2) bunzip + untar this file
|
22
|
+
3) record the location of the 'twitter_stream.txt' file that is in the
|
23
|
+
tarball.
|
24
|
+
4) Pass this file as the first parameter to this script.
|
25
|
+
_
|
26
|
+
|
27
|
+
twitter_stream = ARGV.shift
|
28
|
+
abort README unless twitter_stream and File.readable?( twitter_stream )
|
29
|
+
|
30
|
+
#
|
31
|
+
# Lets create a database that utilizes FTS3 http://www.sqlite.org/fts3.html
|
32
|
+
#
|
33
|
+
#
|
34
|
+
|
35
|
+
#
|
36
|
+
# Create a database, this will create the DB if it doesn't exist
|
37
|
+
#
|
38
|
+
puts "Opening database (version #{Amalgalite::Version})"
|
39
|
+
db = Amalgalite::Database.new("fts3.db")
|
40
|
+
|
41
|
+
#
|
42
|
+
# Create the schema unless it already exists in the table. The meta information
|
43
|
+
# about the database schema is available as the result of the db.schema method
|
44
|
+
#
|
45
|
+
schema = db.schema
|
46
|
+
unless schema.tables['search']
|
47
|
+
puts "Create schema"
|
48
|
+
db.execute_batch <<-SQL
|
49
|
+
CREATE VIRTUAL TABLE search USING fts3(
|
50
|
+
filename VARCHAR(128),
|
51
|
+
content TEXT
|
52
|
+
);
|
53
|
+
|
54
|
+
CREATE TABLE plain (
|
55
|
+
filename VARCHAR(128),
|
56
|
+
content TEXT
|
57
|
+
);
|
58
|
+
SQL
|
59
|
+
db.reload_schema!
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Only load the data if the db is empty
|
64
|
+
#
|
65
|
+
if db.first_value_from( "SELECT count(*) from search" ) == 0 then
|
66
|
+
before = Time.now
|
67
|
+
#
|
68
|
+
# Load the tweets from the file passed on the commandline into the database
|
69
|
+
# We just want the text and the tweet id and insert that into the database.
|
70
|
+
#
|
71
|
+
|
72
|
+
lines = IO.readlines( twitter_stream )
|
73
|
+
idx = 0
|
74
|
+
|
75
|
+
# Inserting bulk rows as a transaction is good practice with SQLite, it is
|
76
|
+
# MUCH faster.
|
77
|
+
db.transaction do |db_in_transaction|
|
78
|
+
lines.each do |line|
|
79
|
+
|
80
|
+
# quick little parse of the tweet
|
81
|
+
json = JSON.parse( line )
|
82
|
+
insert_data = {}
|
83
|
+
insert_data[':fname'] = json['id']
|
84
|
+
insert_data[':content'] = json['text']
|
85
|
+
|
86
|
+
# insert into the FTS3 table
|
87
|
+
db_in_transaction.prepare("INSERT INTO search( filename, content ) VALUES( :fname, :content );") do |stmt|
|
88
|
+
stmt.execute( insert_data )
|
89
|
+
end
|
90
|
+
|
91
|
+
# insert into the normal table for comparison
|
92
|
+
db_in_transaction.prepare("INSERT INTO plain( filename, content ) VALUES( :fname, :content );") do |stmt|
|
93
|
+
stmt.execute( insert_data )
|
94
|
+
end
|
95
|
+
|
96
|
+
idx += 1
|
97
|
+
print "Processed #{idx} of #{lines.size}\r"
|
98
|
+
$stdout.flush
|
99
|
+
end
|
100
|
+
puts "Finalizing..."
|
101
|
+
end
|
102
|
+
puts "Took #{Time.now - before} seconds to insert #{idx} lines of #{lines.size}"
|
103
|
+
puts "Done Inserting"
|
104
|
+
end
|
105
|
+
|
106
|
+
doc_count = db.first_value_from( "SELECT count(*) from search" )
|
107
|
+
|
108
|
+
#
|
109
|
+
# Now lets do some searching for some various words
|
110
|
+
#
|
111
|
+
|
112
|
+
%w[ president salmon thanks ].each do |word|
|
113
|
+
|
114
|
+
count = 100
|
115
|
+
puts
|
116
|
+
puts "Searching for '#{word}' across #{doc_count} tweets"
|
117
|
+
puts "=" * 60
|
118
|
+
|
119
|
+
Benchmark.bm( 15 ) do |x|
|
120
|
+
|
121
|
+
#
|
122
|
+
# search using the fts search to get the cont of tweets with the given word
|
123
|
+
#
|
124
|
+
x.report('fts3: ') do
|
125
|
+
db.prepare( "SELECT count(filename) FROM search WHERE content MATCH '#{word}'" ) do |stmt|
|
126
|
+
count.times do
|
127
|
+
stmt.execute
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
#
|
133
|
+
# search using basic string matching in sqlite.
|
134
|
+
#
|
135
|
+
x.report('plain: ') do
|
136
|
+
db.prepare( "SELECT count(filename) FROM plain WHERE content LIKE '% #{word} %'" ) do |stmt|
|
137
|
+
count.times do
|
138
|
+
stmt.execute
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
@@ -17,10 +17,40 @@ void Init_amalgalite3_constants( )
|
|
17
17
|
*/
|
18
18
|
VALUE mC = rb_define_module_under( mas, "Constants");
|
19
19
|
/**
|
20
|
-
* module encapsulating the SQLite3 C extension constants for Config
|
20
|
+
* module encapsulating the SQLite3 C extension constants for Config
|
21
21
|
*/
|
22
22
|
VALUE mC_Config = rb_define_module_under(mC, "Config");
|
23
23
|
|
24
|
+
/**
|
25
|
+
* module encapsulating the SQLite3 C extension constants for DBStatus
|
26
|
+
*/
|
27
|
+
VALUE mC_DBStatus = rb_define_module_under(mC, "DBStatus");
|
28
|
+
|
29
|
+
/**
|
30
|
+
* module encapsulating the SQLite3 C extension constants for DataType
|
31
|
+
*/
|
32
|
+
VALUE mC_DataType = rb_define_module_under(mC, "DataType");
|
33
|
+
|
34
|
+
/**
|
35
|
+
* module encapsulating the SQLite3 C extension constants for Open
|
36
|
+
*/
|
37
|
+
VALUE mC_Open = rb_define_module_under(mC, "Open");
|
38
|
+
|
39
|
+
/**
|
40
|
+
* module encapsulating the SQLite3 C extension constants for ResultCode
|
41
|
+
*/
|
42
|
+
VALUE mC_ResultCode = rb_define_module_under(mC, "ResultCode");
|
43
|
+
|
44
|
+
/**
|
45
|
+
* module encapsulating the SQLite3 C extension constants for StatementStatus
|
46
|
+
*/
|
47
|
+
VALUE mC_StatementStatus = rb_define_module_under(mC, "StatementStatus");
|
48
|
+
|
49
|
+
/**
|
50
|
+
* module encapsulating the SQLite3 C extension constants for Status
|
51
|
+
*/
|
52
|
+
VALUE mC_Status = rb_define_module_under(mC, "Status");
|
53
|
+
|
24
54
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
25
55
|
rb_define_const(mC_Config, "GETMALLOC", INT2FIX(SQLITE_CONFIG_GETMALLOC));
|
26
56
|
|
@@ -66,11 +96,6 @@ void Init_amalgalite3_constants( )
|
|
66
96
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
67
97
|
rb_define_const(mC_Config, "SINGLETHREAD", INT2FIX(SQLITE_CONFIG_SINGLETHREAD));
|
68
98
|
|
69
|
-
/**
|
70
|
-
* module encapsulating the SQLite3 C extension constants for DBStatus
|
71
|
-
*/
|
72
|
-
VALUE mC_DBStatus = rb_define_module_under(mC, "DBStatus");
|
73
|
-
|
74
99
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
75
100
|
rb_define_const(mC_DBStatus, "CACHE_USED", INT2FIX(SQLITE_DBSTATUS_CACHE_USED));
|
76
101
|
|
@@ -86,11 +111,6 @@ void Init_amalgalite3_constants( )
|
|
86
111
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
87
112
|
rb_define_const(mC_DBStatus, "STMT_USED", INT2FIX(SQLITE_DBSTATUS_STMT_USED));
|
88
113
|
|
89
|
-
/**
|
90
|
-
* module encapsulating the SQLite3 C extension constants for DataType
|
91
|
-
*/
|
92
|
-
VALUE mC_DataType = rb_define_module_under(mC, "DataType");
|
93
|
-
|
94
114
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
95
115
|
rb_define_const(mC_DataType, "BLOB", INT2FIX(SQLITE_BLOB));
|
96
116
|
|
@@ -106,11 +126,6 @@ void Init_amalgalite3_constants( )
|
|
106
126
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
107
127
|
rb_define_const(mC_DataType, "TEXT", INT2FIX(SQLITE_TEXT));
|
108
128
|
|
109
|
-
/**
|
110
|
-
* module encapsulating the SQLite3 C extension constants for Open
|
111
|
-
*/
|
112
|
-
VALUE mC_Open = rb_define_module_under(mC, "Open");
|
113
|
-
|
114
129
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
115
130
|
rb_define_const(mC_Open, "AUTOPROXY", INT2FIX(SQLITE_OPEN_AUTOPROXY));
|
116
131
|
|
@@ -165,11 +180,6 @@ void Init_amalgalite3_constants( )
|
|
165
180
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
166
181
|
rb_define_const(mC_Open, "WAL", INT2FIX(SQLITE_OPEN_WAL));
|
167
182
|
|
168
|
-
/**
|
169
|
-
* module encapsulating the SQLite3 C extension constants for ResultCode
|
170
|
-
*/
|
171
|
-
VALUE mC_ResultCode = rb_define_module_under(mC, "ResultCode");
|
172
|
-
|
173
183
|
/* 4 -- Callback routine requested an abort */
|
174
184
|
rb_define_const(mC_ResultCode, "ABORT", INT2FIX(SQLITE_ABORT));
|
175
185
|
|
@@ -299,7 +309,7 @@ void Init_amalgalite3_constants( )
|
|
299
309
|
/* 26 -- File opened that is not a database file */
|
300
310
|
rb_define_const(mC_ResultCode, "NOTADB", INT2FIX(SQLITE_NOTADB));
|
301
311
|
|
302
|
-
/* 12 --
|
312
|
+
/* 12 -- Unknown opcode in sqlite3_file_control() */
|
303
313
|
rb_define_const(mC_ResultCode, "NOTFOUND", INT2FIX(SQLITE_NOTFOUND));
|
304
314
|
|
305
315
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
@@ -326,11 +336,6 @@ void Init_amalgalite3_constants( )
|
|
326
336
|
/* 18 -- String or BLOB exceeds size limit */
|
327
337
|
rb_define_const(mC_ResultCode, "TOOBIG", INT2FIX(SQLITE_TOOBIG));
|
328
338
|
|
329
|
-
/**
|
330
|
-
* module encapsulating the SQLite3 C extension constants for StatementStatus
|
331
|
-
*/
|
332
|
-
VALUE mC_StatementStatus = rb_define_module_under(mC, "StatementStatus");
|
333
|
-
|
334
339
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
335
340
|
rb_define_const(mC_StatementStatus, "AUTOINDEX", INT2FIX(SQLITE_STMTSTATUS_AUTOINDEX));
|
336
341
|
|
@@ -340,11 +345,6 @@ void Init_amalgalite3_constants( )
|
|
340
345
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
341
346
|
rb_define_const(mC_StatementStatus, "SORT", INT2FIX(SQLITE_STMTSTATUS_SORT));
|
342
347
|
|
343
|
-
/**
|
344
|
-
* module encapsulating the SQLite3 C extension constants for Status
|
345
|
-
*/
|
346
|
-
VALUE mC_Status = rb_define_module_under(mC, "Status");
|
347
|
-
|
348
348
|
/* no meaningful autogenerated documentation -- constant is self explanatory ?*/
|
349
349
|
rb_define_const(mC_Status, "MALLOC_COUNT", INT2FIX(SQLITE_STATUS_MALLOC_COUNT));
|
350
350
|
|
data/ext/amalgalite/extconf.rb
CHANGED
@@ -8,6 +8,9 @@ $ruby = ARGV.shift if ARGV[0]
|
|
8
8
|
# make available table and column meta data api
|
9
9
|
$CFLAGS += " -DSQLITE_ENABLE_COLUMN_METADATA=1"
|
10
10
|
$CFLAGS += " -DSQLITE_ENABLE_RTREE=1"
|
11
|
+
$CFLAGS += " -DSQLITE_ENABLE_FTS3=1"
|
12
|
+
$CFLAGS += " -DSQLITE_ENABLE_FTS3_PARENTHESIS=1"
|
13
|
+
$CFLAGS += " -DSQLITE_ENABLE_STAT2=1"
|
11
14
|
|
12
15
|
# we compile sqlite the same way that the installation of ruby is compiled.
|
13
16
|
if RbConfig::MAKEFILE_CONFIG['configure_args'].include?( "--enable-pthread" ) then
|
@@ -170,10 +170,14 @@ File.open(fname, "w+") do |f|
|
|
170
170
|
CONSTANTS.keys.sort.each do |klass|
|
171
171
|
const_set = CONSTANTS[klass]
|
172
172
|
f.puts " /**"
|
173
|
-
f.puts " * module encapsulating the SQLite3 C extension constants for #{klass}
|
173
|
+
f.puts " * module encapsulating the SQLite3 C extension constants for #{klass}"
|
174
174
|
f.puts " */"
|
175
175
|
f.puts " VALUE mC_#{klass} = rb_define_module_under(mC, \"#{klass}\");"
|
176
176
|
f.puts
|
177
|
+
end
|
178
|
+
|
179
|
+
CONSTANTS.keys.sort.each do |klass|
|
180
|
+
const_set = CONSTANTS[klass]
|
177
181
|
const_set.keys.sort.each do |k|
|
178
182
|
sql_const = const_set[k]
|
179
183
|
const_doc = " /* no meaningful autogenerated documentation -- constant is self explanatory ?*/"
|
data/ext/amalgalite/sqlite3.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/******************************************************************************
|
2
2
|
** This file is an amalgamation of many separate C source files from SQLite
|
3
|
-
** version 3.7.
|
3
|
+
** version 3.7.5. By combining all the individual C code files into this
|
4
4
|
** single large file, the entire code can be compiled as a one translation
|
5
5
|
** unit. This allows many compilers to do optimizations that would not be
|
6
6
|
** possible if the files were compiled separately. Performance improvements
|
@@ -650,9 +650,9 @@ extern "C" {
|
|
650
650
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
651
651
|
** [sqlite_version()] and [sqlite_source_id()].
|
652
652
|
*/
|
653
|
-
#define SQLITE_VERSION "3.7.
|
654
|
-
#define SQLITE_VERSION_NUMBER
|
655
|
-
#define SQLITE_SOURCE_ID "
|
653
|
+
#define SQLITE_VERSION "3.7.5"
|
654
|
+
#define SQLITE_VERSION_NUMBER 3007005
|
655
|
+
#define SQLITE_SOURCE_ID "2011-01-28 17:03:50 ed759d5a9edb3bba5f48f243df47be29e3fe8cd7"
|
656
656
|
|
657
657
|
/*
|
658
658
|
** CAPI3REF: Run-Time Library Version Numbers
|
@@ -933,7 +933,7 @@ SQLITE_API int sqlite3_exec(
|
|
933
933
|
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
|
934
934
|
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
|
935
935
|
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
|
936
|
-
#define SQLITE_NOTFOUND 12 /*
|
936
|
+
#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */
|
937
937
|
#define SQLITE_FULL 13 /* Insertion failed because database is full */
|
938
938
|
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
|
939
939
|
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
|
@@ -1165,7 +1165,9 @@ struct sqlite3_file {
|
|
1165
1165
|
** core reserves all opcodes less than 100 for its own use.
|
1166
1166
|
** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
|
1167
1167
|
** Applications that define a custom xFileControl method should use opcodes
|
1168
|
-
** greater than 100 to avoid conflicts.
|
1168
|
+
** greater than 100 to avoid conflicts. VFS implementations should
|
1169
|
+
** return [SQLITE_NOTFOUND] for file control opcodes that they do not
|
1170
|
+
** recognize.
|
1169
1171
|
**
|
1170
1172
|
** The xSectorSize() method returns the sector size of the
|
1171
1173
|
** device that underlies the file. The sector size is the
|
@@ -1258,6 +1260,21 @@ struct sqlite3_io_methods {
|
|
1258
1260
|
** for the nominated database. Allocating database file space in large
|
1259
1261
|
** chunks (say 1MB at a time), may reduce file-system fragmentation and
|
1260
1262
|
** improve performance on some systems.
|
1263
|
+
**
|
1264
|
+
** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer
|
1265
|
+
** to the [sqlite3_file] object associated with a particular database
|
1266
|
+
** connection. See the [sqlite3_file_control()] documentation for
|
1267
|
+
** additional information.
|
1268
|
+
**
|
1269
|
+
** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
|
1270
|
+
** SQLite and sent to all VFSes in place of a call to the xSync method
|
1271
|
+
** when the database connection has [PRAGMA synchronous] set to OFF.)^
|
1272
|
+
** Some specialized VFSes need this signal in order to operate correctly
|
1273
|
+
** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most
|
1274
|
+
** VFSes do not need this signal and should silently ignore this opcode.
|
1275
|
+
** Applications should not call [sqlite3_file_control()] with this
|
1276
|
+
** opcode as doing so may disrupt the operation of the specilized VFSes
|
1277
|
+
** that do require it.
|
1261
1278
|
*/
|
1262
1279
|
#define SQLITE_FCNTL_LOCKSTATE 1
|
1263
1280
|
#define SQLITE_GET_LOCKPROXYFILE 2
|
@@ -1266,6 +1283,7 @@ struct sqlite3_io_methods {
|
|
1266
1283
|
#define SQLITE_FCNTL_SIZE_HINT 5
|
1267
1284
|
#define SQLITE_FCNTL_CHUNK_SIZE 6
|
1268
1285
|
#define SQLITE_FCNTL_FILE_POINTER 7
|
1286
|
+
#define SQLITE_FCNTL_SYNC_OMITTED 8
|
1269
1287
|
|
1270
1288
|
|
1271
1289
|
/*
|
@@ -2385,7 +2403,7 @@ SQLITE_API void sqlite3_free_table(char **result);
|
|
2385
2403
|
** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
|
2386
2404
|
** memory to hold the resulting string.
|
2387
2405
|
**
|
2388
|
-
** ^(
|
2406
|
+
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
|
2389
2407
|
** the standard C library. The result is written into the
|
2390
2408
|
** buffer supplied as the second parameter whose size is given by
|
2391
2409
|
** the first parameter. Note that the order of the
|
@@ -2404,6 +2422,8 @@ SQLITE_API void sqlite3_free_table(char **result);
|
|
2404
2422
|
** the zero terminator. So the longest string that can be completely
|
2405
2423
|
** written will be n-1 characters.
|
2406
2424
|
**
|
2425
|
+
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
|
2426
|
+
**
|
2407
2427
|
** These routines all implement some additional formatting
|
2408
2428
|
** options that are useful for constructing SQL statements.
|
2409
2429
|
** All of the usual printf() formatting options apply. In addition, there
|
@@ -2467,6 +2487,7 @@ SQLITE_API void sqlite3_free_table(char **result);
|
|
2467
2487
|
SQLITE_API char *sqlite3_mprintf(const char*,...);
|
2468
2488
|
SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
|
2469
2489
|
SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
|
2490
|
+
SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
|
2470
2491
|
|
2471
2492
|
/*
|
2472
2493
|
** CAPI3REF: Memory Allocation Subsystem
|
@@ -2844,7 +2865,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
|
2844
2865
|
** case the database must already exist, otherwise an error is returned.</dd>)^
|
2845
2866
|
**
|
2846
2867
|
** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
|
2847
|
-
** <dd>The database is opened for reading and writing, and is
|
2868
|
+
** <dd>The database is opened for reading and writing, and is created if
|
2848
2869
|
** it does not already exist. This is the behavior that is always used for
|
2849
2870
|
** sqlite3_open() and sqlite3_open16().</dd>)^
|
2850
2871
|
** </dl>
|
@@ -3193,14 +3214,31 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
|
|
3193
3214
|
/*
|
3194
3215
|
** CAPI3REF: Determine If An SQL Statement Writes The Database
|
3195
3216
|
**
|
3196
|
-
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
|
3197
|
-
** the [prepared statement] X
|
3198
|
-
**
|
3199
|
-
**
|
3200
|
-
**
|
3201
|
-
**
|
3202
|
-
**
|
3203
|
-
**
|
3217
|
+
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
|
3218
|
+
** and only if the [prepared statement] X makes no direct changes to
|
3219
|
+
** the content of the database file.
|
3220
|
+
**
|
3221
|
+
** Note that [application-defined SQL functions] or
|
3222
|
+
** [virtual tables] might change the database indirectly as a side effect.
|
3223
|
+
** ^(For example, if an application defines a function "eval()" that
|
3224
|
+
** calls [sqlite3_exec()], then the following SQL statement would
|
3225
|
+
** change the database file through side-effects:
|
3226
|
+
**
|
3227
|
+
** <blockquote><pre>
|
3228
|
+
** SELECT eval('DELETE FROM t1') FROM t2;
|
3229
|
+
** </pre></blockquote>
|
3230
|
+
**
|
3231
|
+
** But because the [SELECT] statement does not change the database file
|
3232
|
+
** directly, sqlite3_stmt_readonly() would still return true.)^
|
3233
|
+
**
|
3234
|
+
** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK],
|
3235
|
+
** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true,
|
3236
|
+
** since the statements themselves do not actually modify the database but
|
3237
|
+
** rather they control the timing of when other statements modify the
|
3238
|
+
** database. ^The [ATTACH] and [DETACH] statements also cause
|
3239
|
+
** sqlite3_stmt_readonly() to return true since, while those statements
|
3240
|
+
** change the configuration of a database connection, they do not make
|
3241
|
+
** changes to the content of the database files on disk.
|
3204
3242
|
*/
|
3205
3243
|
SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
|
3206
3244
|
|
@@ -3594,13 +3632,17 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
|
|
3594
3632
|
** be the case that the same database connection is being used by two or
|
3595
3633
|
** more threads at the same moment in time.
|
3596
3634
|
**
|
3597
|
-
** For all versions of SQLite up to and including 3.6.23.1,
|
3598
|
-
** after sqlite3_step() returned anything
|
3599
|
-
** [
|
3600
|
-
** sqlite3_step(). Failure to
|
3601
|
-
** result in an [SQLITE_MISUSE] return from
|
3602
|
-
** version 3.6.23.1, sqlite3_step() began
|
3603
|
-
** automatically in this circumstance rather
|
3635
|
+
** For all versions of SQLite up to and including 3.6.23.1, a call to
|
3636
|
+
** [sqlite3_reset()] was required after sqlite3_step() returned anything
|
3637
|
+
** other than [SQLITE_ROW] before any subsequent invocation of
|
3638
|
+
** sqlite3_step(). Failure to reset the prepared statement using
|
3639
|
+
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
|
3640
|
+
** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began
|
3641
|
+
** calling [sqlite3_reset()] automatically in this circumstance rather
|
3642
|
+
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
|
3643
|
+
** break because any application that ever receives an SQLITE_MISUSE error
|
3644
|
+
** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option
|
3645
|
+
** can be used to restore the legacy behavior.
|
3604
3646
|
**
|
3605
3647
|
** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
|
3606
3648
|
** API always returns a generic error code, [SQLITE_ERROR], following any
|
@@ -3937,7 +3979,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
|
3937
3979
|
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
3938
3980
|
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
3939
3981
|
**
|
3940
|
-
** ^The
|
3982
|
+
** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
|
3941
3983
|
** pointers to C-language functions that implement the SQL function or
|
3942
3984
|
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
|
3943
3985
|
** callback only; NULL pointers must be passed as the xStep and xFinal
|
@@ -3946,7 +3988,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
|
3946
3988
|
** SQL function or aggregate, pass NULL poiners for all three function
|
3947
3989
|
** callbacks.
|
3948
3990
|
**
|
3949
|
-
** ^(If the
|
3991
|
+
** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
|
3950
3992
|
** then it is destructor for the application data pointer.
|
3951
3993
|
** The destructor is invoked when the function is deleted, either by being
|
3952
3994
|
** overloaded or when the database connection closes.)^
|
@@ -4050,7 +4092,7 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
|
|
4050
4092
|
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
|
4051
4093
|
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
|
4052
4094
|
** define callbacks that implement the SQL functions and aggregates.
|
4053
|
-
** The
|
4095
|
+
** The 3rd parameter to these callbacks is an array of pointers to
|
4054
4096
|
** [protected sqlite3_value] objects. There is one [sqlite3_value] object for
|
4055
4097
|
** each parameter to the SQL function. These routines are used to
|
4056
4098
|
** extract values from the [sqlite3_value] objects.
|
@@ -5778,7 +5820,8 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
|
|
5778
5820
|
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
|
5779
5821
|
#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
|
5780
5822
|
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
|
5781
|
-
#define SQLITE_MUTEX_STATIC_LRU2 7 /*
|
5823
|
+
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
|
5824
|
+
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
|
5782
5825
|
|
5783
5826
|
/*
|
5784
5827
|
** CAPI3REF: Retrieve the mutex for a database connection
|
@@ -5929,7 +5972,8 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
|
|
5929
5972
|
** The value written into the *pCurrent parameter is undefined.</dd>)^
|
5930
5973
|
**
|
5931
5974
|
** ^(<dt>SQLITE_STATUS_MALLOC_COUNT</dt>
|
5932
|
-
** <dd>This parameter records the number of separate memory allocations
|
5975
|
+
** <dd>This parameter records the number of separate memory allocations
|
5976
|
+
** currently checked out.</dd>)^
|
5933
5977
|
**
|
5934
5978
|
** ^(<dt>SQLITE_STATUS_PAGECACHE_USED</dt>
|
5935
5979
|
** <dd>This parameter returns the number of pages used out of the
|
@@ -6035,6 +6079,28 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
|
|
6035
6079
|
** <dd>This parameter returns the number of lookaside memory slots currently
|
6036
6080
|
** checked out.</dd>)^
|
6037
6081
|
**
|
6082
|
+
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
|
6083
|
+
** <dd>This parameter returns the number malloc attempts that were
|
6084
|
+
** satisfied using lookaside memory. Only the high-water value is meaningful;
|
6085
|
+
** the current value is always zero.
|
6086
|
+
** checked out.</dd>)^
|
6087
|
+
**
|
6088
|
+
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE</dt>
|
6089
|
+
** <dd>This parameter returns the number malloc attempts that might have
|
6090
|
+
** been satisfied using lookaside memory but failed due to the amount of
|
6091
|
+
** memory requested being larger than the lookaside slot size.
|
6092
|
+
** Only the high-water value is meaningful;
|
6093
|
+
** the current value is always zero.
|
6094
|
+
** checked out.</dd>)^
|
6095
|
+
**
|
6096
|
+
** ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL</dt>
|
6097
|
+
** <dd>This parameter returns the number malloc attempts that might have
|
6098
|
+
** been satisfied using lookaside memory but failed due to all lookaside
|
6099
|
+
** memory already being in use.
|
6100
|
+
** Only the high-water value is meaningful;
|
6101
|
+
** the current value is always zero.
|
6102
|
+
** checked out.</dd>)^
|
6103
|
+
**
|
6038
6104
|
** ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
|
6039
6105
|
** <dd>This parameter returns the approximate number of of bytes of heap
|
6040
6106
|
** memory used by all pager caches associated with the database connection.)^
|
@@ -6057,11 +6123,14 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
|
|
6057
6123
|
** </dd>
|
6058
6124
|
** </dl>
|
6059
6125
|
*/
|
6060
|
-
#define SQLITE_DBSTATUS_LOOKASIDE_USED
|
6061
|
-
#define SQLITE_DBSTATUS_CACHE_USED
|
6062
|
-
#define SQLITE_DBSTATUS_SCHEMA_USED
|
6063
|
-
#define SQLITE_DBSTATUS_STMT_USED
|
6064
|
-
#define
|
6126
|
+
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
|
6127
|
+
#define SQLITE_DBSTATUS_CACHE_USED 1
|
6128
|
+
#define SQLITE_DBSTATUS_SCHEMA_USED 2
|
6129
|
+
#define SQLITE_DBSTATUS_STMT_USED 3
|
6130
|
+
#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
|
6131
|
+
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
|
6132
|
+
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
|
6133
|
+
#define SQLITE_DBSTATUS_MAX 6 /* Largest defined DBSTATUS */
|
6065
6134
|
|
6066
6135
|
|
6067
6136
|
/*
|
@@ -6189,11 +6258,13 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
|
6189
6258
|
** first parameter, szPage, is the size in bytes of the pages that must
|
6190
6259
|
** be allocated by the cache. ^szPage will not be a power of two. ^szPage
|
6191
6260
|
** will the page size of the database file that is to be cached plus an
|
6192
|
-
** increment (here called "R") of
|
6261
|
+
** increment (here called "R") of less than 250. SQLite will use the
|
6193
6262
|
** extra R bytes on each page to store metadata about the underlying
|
6194
6263
|
** database page on disk. The value of R depends
|
6195
6264
|
** on the SQLite version, the target platform, and how SQLite was compiled.
|
6196
|
-
** ^R is constant for a particular build of SQLite.
|
6265
|
+
** ^(R is constant for a particular build of SQLite. Except, there are two
|
6266
|
+
** distinct values of R when SQLite is compiled with the proprietary
|
6267
|
+
** ZIPVFS extension.)^ ^The second argument to
|
6197
6268
|
** xCreate(), bPurgeable, is true if the cache being created will
|
6198
6269
|
** be used to cache database pages of a file stored on disk, or
|
6199
6270
|
** false if it is used for an in-memory database. The cache implementation
|
@@ -6225,7 +6296,7 @@ typedef struct sqlite3_pcache sqlite3_pcache;
|
|
6225
6296
|
** If the requested page is already in the page cache, then the page cache
|
6226
6297
|
** implementation must return a pointer to the page buffer with its content
|
6227
6298
|
** intact. If the requested page is not already in the cache, then the
|
6228
|
-
**
|
6299
|
+
** cache implementation should use the value of the createFlag
|
6229
6300
|
** parameter to help it determined what action to take:
|
6230
6301
|
**
|
6231
6302
|
** <table border=1 width=85% align=center>
|
@@ -6309,11 +6380,12 @@ typedef struct sqlite3_backup sqlite3_backup;
|
|
6309
6380
|
**
|
6310
6381
|
** See Also: [Using the SQLite Online Backup API]
|
6311
6382
|
**
|
6312
|
-
** ^
|
6313
|
-
** duration of the operation.
|
6314
|
-
** read-locked while it is
|
6315
|
-
** continuously for the entire backup operation.
|
6316
|
-
** performed on a live source database without
|
6383
|
+
** ^SQLite holds a write transaction open on the destination database file
|
6384
|
+
** for the duration of the backup operation.
|
6385
|
+
** ^The source database is read-locked only while it is being read;
|
6386
|
+
** it is not locked continuously for the entire backup operation.
|
6387
|
+
** ^Thus, the backup may be performed on a live source database without
|
6388
|
+
** preventing other database connections from
|
6317
6389
|
** reading or writing to the source database while the backup is underway.
|
6318
6390
|
**
|
6319
6391
|
** ^(To perform a backup operation:
|
@@ -6340,11 +6412,11 @@ typedef struct sqlite3_backup sqlite3_backup;
|
|
6340
6412
|
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
|
6341
6413
|
** and database name of the source database, respectively.
|
6342
6414
|
** ^The source and destination [database connections] (parameters S and D)
|
6343
|
-
** must be different or else sqlite3_backup_init(D,N,S,M) will
|
6415
|
+
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
|
6344
6416
|
** an error.
|
6345
6417
|
**
|
6346
6418
|
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
|
6347
|
-
** returned and an error code and error message are
|
6419
|
+
** returned and an error code and error message are stored in the
|
6348
6420
|
** destination [database connection] D.
|
6349
6421
|
** ^The error code and message for the failed call to sqlite3_backup_init()
|
6350
6422
|
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
|
@@ -6361,7 +6433,7 @@ typedef struct sqlite3_backup sqlite3_backup;
|
|
6361
6433
|
** the source and destination databases specified by [sqlite3_backup] object B.
|
6362
6434
|
** ^If N is negative, all remaining source pages are copied.
|
6363
6435
|
** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
|
6364
|
-
** are still more pages to be copied, then the function
|
6436
|
+
** are still more pages to be copied, then the function returns [SQLITE_OK].
|
6365
6437
|
** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
|
6366
6438
|
** from source to destination, then it returns [SQLITE_DONE].
|
6367
6439
|
** ^If an error occurs while running sqlite3_backup_step(B,N),
|
@@ -6375,7 +6447,7 @@ typedef struct sqlite3_backup sqlite3_backup;
|
|
6375
6447
|
** <li> the destination database was opened read-only, or
|
6376
6448
|
** <li> the destination database is using write-ahead-log journaling
|
6377
6449
|
** and the destination and source page sizes differ, or
|
6378
|
-
** <li>
|
6450
|
+
** <li> the destination database is an in-memory database and the
|
6379
6451
|
** destination and source page sizes differ.
|
6380
6452
|
** </ol>)^
|
6381
6453
|
**
|
@@ -6706,7 +6778,8 @@ SQLITE_API void *sqlite3_wal_hook(
|
|
6706
6778
|
** from SQL.
|
6707
6779
|
**
|
6708
6780
|
** ^Every new [database connection] defaults to having the auto-checkpoint
|
6709
|
-
** enabled with a threshold of 1000
|
6781
|
+
** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT]
|
6782
|
+
** pages. The use of this interface
|
6710
6783
|
** is only necessary if the default setting is found to be suboptimal
|
6711
6784
|
** for a particular application.
|
6712
6785
|
*/
|
@@ -8877,6 +8950,7 @@ struct Lookaside {
|
|
8877
8950
|
u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
|
8878
8951
|
int nOut; /* Number of buffers currently checked out */
|
8879
8952
|
int mxOut; /* Highwater mark for nOut */
|
8953
|
+
int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
|
8880
8954
|
LookasideSlot *pFree; /* List of available buffers */
|
8881
8955
|
void *pStart; /* First byte of available memory space */
|
8882
8956
|
void *pEnd; /* First byte past end of available space */
|
@@ -8955,6 +9029,7 @@ struct sqlite3 {
|
|
8955
9029
|
struct Vdbe *pVdbe; /* List of active virtual machines */
|
8956
9030
|
int activeVdbeCnt; /* Number of VDBEs currently executing */
|
8957
9031
|
int writeVdbeCnt; /* Number of active VDBEs that are writing */
|
9032
|
+
int vdbeExecCnt; /* Number of nested calls to VdbeExec() */
|
8958
9033
|
void (*xTrace)(void*,const char*); /* Trace function */
|
8959
9034
|
void *pTraceArg; /* Argument to the trace function */
|
8960
9035
|
void (*xProfile)(void*,const char*,u64); /* Profiling function */
|
@@ -11727,6 +11802,9 @@ static const char * const azCompileOpt[] = {
|
|
11727
11802
|
#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
|
11728
11803
|
"OMIT_AUTOMATIC_INDEX",
|
11729
11804
|
#endif
|
11805
|
+
#ifdef SQLITE_OMIT_AUTORESET
|
11806
|
+
"OMIT_AUTORESET",
|
11807
|
+
#endif
|
11730
11808
|
#ifdef SQLITE_OMIT_AUTOVACUUM
|
11731
11809
|
"OMIT_AUTOVACUUM",
|
11732
11810
|
#endif
|
@@ -12002,16 +12080,14 @@ typedef unsigned char Bool;
|
|
12002
12080
|
**
|
12003
12081
|
** Every cursor that the virtual machine has open is represented by an
|
12004
12082
|
** instance of the following structure.
|
12005
|
-
**
|
12006
|
-
** If the VdbeCursor.isTriggerRow flag is set it means that this cursor is
|
12007
|
-
** really a single row that represents the NEW or OLD pseudo-table of
|
12008
|
-
** a row trigger. The data for the row is stored in VdbeCursor.pData and
|
12009
|
-
** the rowid is in VdbeCursor.iKey.
|
12010
12083
|
*/
|
12011
12084
|
struct VdbeCursor {
|
12012
12085
|
BtCursor *pCursor; /* The cursor structure of the backend */
|
12086
|
+
Btree *pBt; /* Separate file holding temporary table */
|
12087
|
+
KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
|
12013
12088
|
int iDb; /* Index of cursor database in db->aDb[] (or -1) */
|
12014
|
-
|
12089
|
+
int pseudoTableReg; /* Register holding pseudotable content. */
|
12090
|
+
int nField; /* Number of fields in the header */
|
12015
12091
|
Bool zeroed; /* True if zeroed out and ready for reuse */
|
12016
12092
|
Bool rowidIsValid; /* True if lastRowid is valid */
|
12017
12093
|
Bool atFirst; /* True if pointing to first entry */
|
@@ -12021,14 +12097,11 @@ struct VdbeCursor {
|
|
12021
12097
|
Bool isTable; /* True if a table requiring integer keys */
|
12022
12098
|
Bool isIndex; /* True if an index containing keys only - no data */
|
12023
12099
|
Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */
|
12024
|
-
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
|
12025
|
-
Btree *pBt; /* Separate file holding temporary table */
|
12026
|
-
int pseudoTableReg; /* Register holding pseudotable content. */
|
12027
|
-
KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
|
12028
|
-
int nField; /* Number of fields in the header */
|
12029
|
-
i64 seqCount; /* Sequence counter */
|
12030
12100
|
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
|
12031
12101
|
const sqlite3_module *pModule; /* Module for cursor pVtabCursor */
|
12102
|
+
i64 seqCount; /* Sequence counter */
|
12103
|
+
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
|
12104
|
+
i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
|
12032
12105
|
|
12033
12106
|
/* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or
|
12034
12107
|
** OP_IsUnique opcode on this cursor. */
|
@@ -12100,25 +12173,19 @@ struct VdbeFrame {
|
|
12100
12173
|
/*
|
12101
12174
|
** Internally, the vdbe manipulates nearly all SQL values as Mem
|
12102
12175
|
** structures. Each Mem struct may cache multiple representations (string,
|
12103
|
-
** integer etc.) of the same value.
|
12104
|
-
** has the following properties:
|
12105
|
-
**
|
12106
|
-
** Each value has a manifest type. The manifest type of the value stored
|
12107
|
-
** in a Mem struct is returned by the MemType(Mem*) macro. The type is
|
12108
|
-
** one of SQLITE_NULL, SQLITE_INTEGER, SQLITE_REAL, SQLITE_TEXT or
|
12109
|
-
** SQLITE_BLOB.
|
12176
|
+
** integer etc.) of the same value.
|
12110
12177
|
*/
|
12111
12178
|
struct Mem {
|
12179
|
+
sqlite3 *db; /* The associated database connection */
|
12180
|
+
char *z; /* String or BLOB value */
|
12181
|
+
double r; /* Real value */
|
12112
12182
|
union {
|
12113
|
-
i64 i; /* Integer value
|
12183
|
+
i64 i; /* Integer value used when MEM_Int is set in flags */
|
12114
12184
|
int nZero; /* Used when bit MEM_Zero is set in flags */
|
12115
12185
|
FuncDef *pDef; /* Used only when flags==MEM_Agg */
|
12116
12186
|
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
|
12117
12187
|
VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
|
12118
12188
|
} u;
|
12119
|
-
double r; /* Real value */
|
12120
|
-
sqlite3 *db; /* The associated database connection */
|
12121
|
-
char *z; /* String or BLOB value */
|
12122
12189
|
int n; /* Number of characters in string value, excluding '\0' */
|
12123
12190
|
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
|
12124
12191
|
u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
|
@@ -12142,9 +12209,6 @@ struct Mem {
|
|
12142
12209
|
** database (see below for exceptions). If the MEM_Term flag is also
|
12143
12210
|
** set, then the string is nul terminated. The MEM_Int and MEM_Real
|
12144
12211
|
** flags may coexist with the MEM_Str flag.
|
12145
|
-
**
|
12146
|
-
** Multiple of these values can appear in Mem.flags. But only one
|
12147
|
-
** at a time can appear in Mem.type.
|
12148
12212
|
*/
|
12149
12213
|
#define MEM_Null 0x0001 /* Value is NULL */
|
12150
12214
|
#define MEM_Str 0x0002 /* Value is a string */
|
@@ -12227,23 +12291,11 @@ struct sqlite3_context {
|
|
12227
12291
|
CollSeq *pColl; /* Collating sequence */
|
12228
12292
|
};
|
12229
12293
|
|
12230
|
-
/*
|
12231
|
-
** A Set structure is used for quick testing to see if a value
|
12232
|
-
** is part of a small set. Sets are used to implement code like
|
12233
|
-
** this:
|
12234
|
-
** x.y IN ('hi','hoo','hum')
|
12235
|
-
*/
|
12236
|
-
typedef struct Set Set;
|
12237
|
-
struct Set {
|
12238
|
-
Hash hash; /* A set is just a hash table */
|
12239
|
-
HashElem *prev; /* Previously accessed hash elemen */
|
12240
|
-
};
|
12241
|
-
|
12242
12294
|
/*
|
12243
12295
|
** An instance of the virtual machine. This structure contains the complete
|
12244
12296
|
** state of the virtual machine.
|
12245
12297
|
**
|
12246
|
-
** The "sqlite3_stmt" structure pointer that is returned by
|
12298
|
+
** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
|
12247
12299
|
** is really a pointer to an instance of this structure.
|
12248
12300
|
**
|
12249
12301
|
** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
|
@@ -12256,31 +12308,31 @@ struct Set {
|
|
12256
12308
|
*/
|
12257
12309
|
struct Vdbe {
|
12258
12310
|
sqlite3 *db; /* The database connection that owns this statement */
|
12259
|
-
|
12311
|
+
Op *aOp; /* Space to hold the virtual machine's program */
|
12312
|
+
Mem *aMem; /* The memory locations */
|
12313
|
+
Mem **apArg; /* Arguments to currently executing user function */
|
12314
|
+
Mem *aColName; /* Column names to return */
|
12315
|
+
Mem *pResultSet; /* Pointer to an array of results */
|
12316
|
+
int nMem; /* Number of memory locations currently allocated */
|
12260
12317
|
int nOp; /* Number of instructions in the program */
|
12261
12318
|
int nOpAlloc; /* Number of slots allocated for aOp[] */
|
12262
|
-
Op *aOp; /* Space to hold the virtual machine's program */
|
12263
12319
|
int nLabel; /* Number of labels used */
|
12264
12320
|
int nLabelAlloc; /* Number of slots allocated in aLabel[] */
|
12265
12321
|
int *aLabel; /* Space to hold the labels */
|
12266
|
-
Mem **apArg; /* Arguments to currently executing user function */
|
12267
|
-
Mem *aColName; /* Column names to return */
|
12268
|
-
Mem *pResultSet; /* Pointer to an array of results */
|
12269
12322
|
u16 nResColumn; /* Number of columns in one row of the result set */
|
12270
12323
|
u16 nCursor; /* Number of slots in apCsr[] */
|
12324
|
+
u32 magic; /* Magic number for sanity checking */
|
12325
|
+
char *zErrMsg; /* Error message written here */
|
12326
|
+
Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
|
12271
12327
|
VdbeCursor **apCsr; /* One element of this array for each open cursor */
|
12272
|
-
u8 errorAction; /* Recovery action to do in case of an error */
|
12273
|
-
u8 okVar; /* True if azVar[] has been initialized */
|
12274
|
-
ynVar nVar; /* Number of entries in aVar[] */
|
12275
12328
|
Mem *aVar; /* Values for the OP_Variable opcode. */
|
12276
12329
|
char **azVar; /* Name of variables */
|
12277
|
-
|
12278
|
-
int nMem; /* Number of memory locations currently allocated */
|
12279
|
-
Mem *aMem; /* The memory locations */
|
12330
|
+
ynVar nVar; /* Number of entries in aVar[] */
|
12280
12331
|
u32 cacheCtr; /* VdbeCursor row cache generation counter */
|
12281
12332
|
int pc; /* The program counter */
|
12282
12333
|
int rc; /* Value to return */
|
12283
|
-
|
12334
|
+
u8 errorAction; /* Recovery action to do in case of an error */
|
12335
|
+
u8 okVar; /* True if azVar[] has been initialized */
|
12284
12336
|
u8 explain; /* True if EXPLAIN present on SQL command */
|
12285
12337
|
u8 changeCntOn; /* True to update the change-counter */
|
12286
12338
|
u8 expired; /* True if the VM needs to be recompiled */
|
@@ -12292,14 +12344,16 @@ struct Vdbe {
|
|
12292
12344
|
u8 isPrepareV2; /* True if prepared with prepare_v2() */
|
12293
12345
|
int nChange; /* Number of db changes made since last reset */
|
12294
12346
|
int btreeMask; /* Bitmask of db->aDb[] entries referenced */
|
12295
|
-
|
12296
|
-
BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
|
12347
|
+
int iStatement; /* Statement number (or 0 if has not opened stmt) */
|
12297
12348
|
int aCounter[3]; /* Counters used by sqlite3_stmt_status() */
|
12298
|
-
|
12299
|
-
|
12349
|
+
BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */
|
12350
|
+
#ifndef SQLITE_OMIT_TRACE
|
12351
|
+
i64 startTime; /* Time when query started - used for profiling */
|
12352
|
+
#endif
|
12300
12353
|
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
|
12301
12354
|
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
|
12302
|
-
|
12355
|
+
char *zSql; /* Text of the SQL statement that generated this */
|
12356
|
+
void *pFree; /* Free this when deleting the vdbe */
|
12303
12357
|
#ifdef SQLITE_DEBUG
|
12304
12358
|
FILE *trace; /* Write an execution trace here, if not NULL */
|
12305
12359
|
#endif
|
@@ -12509,6 +12563,22 @@ SQLITE_API int sqlite3_db_status(
|
|
12509
12563
|
break;
|
12510
12564
|
}
|
12511
12565
|
|
12566
|
+
case SQLITE_DBSTATUS_LOOKASIDE_HIT:
|
12567
|
+
case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
|
12568
|
+
case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
|
12569
|
+
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
|
12570
|
+
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
|
12571
|
+
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
|
12572
|
+
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
|
12573
|
+
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
|
12574
|
+
*pCurrent = 0;
|
12575
|
+
*pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT];
|
12576
|
+
if( resetFlag ){
|
12577
|
+
db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
|
12578
|
+
}
|
12579
|
+
break;
|
12580
|
+
}
|
12581
|
+
|
12512
12582
|
/*
|
12513
12583
|
** Return an approximation for the amount of memory currently used
|
12514
12584
|
** by all pagers associated with the given database connection. The
|
@@ -16867,7 +16937,7 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; }
|
|
16867
16937
|
** <li> SQLITE_MUTEX_STATIC_MEM2
|
16868
16938
|
** <li> SQLITE_MUTEX_STATIC_PRNG
|
16869
16939
|
** <li> SQLITE_MUTEX_STATIC_LRU
|
16870
|
-
** <li>
|
16940
|
+
** <li> SQLITE_MUTEX_STATIC_PMEM
|
16871
16941
|
** </ul>
|
16872
16942
|
**
|
16873
16943
|
** The first two constants cause sqlite3_mutex_alloc() to create
|
@@ -17277,7 +17347,7 @@ static int winMutexEnd(void){
|
|
17277
17347
|
** <li> SQLITE_MUTEX_STATIC_MEM2
|
17278
17348
|
** <li> SQLITE_MUTEX_STATIC_PRNG
|
17279
17349
|
** <li> SQLITE_MUTEX_STATIC_LRU
|
17280
|
-
** <li>
|
17350
|
+
** <li> SQLITE_MUTEX_STATIC_PMEM
|
17281
17351
|
** </ul>
|
17282
17352
|
**
|
17283
17353
|
** The first two constants cause sqlite3_mutex_alloc() to create
|
@@ -18070,14 +18140,20 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
|
|
18070
18140
|
if( db->mallocFailed ){
|
18071
18141
|
return 0;
|
18072
18142
|
}
|
18073
|
-
if( db->lookaside.bEnabled
|
18074
|
-
|
18075
|
-
|
18076
|
-
db->lookaside.
|
18077
|
-
|
18078
|
-
|
18143
|
+
if( db->lookaside.bEnabled ){
|
18144
|
+
if( n>db->lookaside.sz ){
|
18145
|
+
db->lookaside.anStat[1]++;
|
18146
|
+
}else if( (pBuf = db->lookaside.pFree)==0 ){
|
18147
|
+
db->lookaside.anStat[2]++;
|
18148
|
+
}else{
|
18149
|
+
db->lookaside.pFree = pBuf->pNext;
|
18150
|
+
db->lookaside.nOut++;
|
18151
|
+
db->lookaside.anStat[0]++;
|
18152
|
+
if( db->lookaside.nOut>db->lookaside.mxOut ){
|
18153
|
+
db->lookaside.mxOut = db->lookaside.nOut;
|
18154
|
+
}
|
18155
|
+
return (void*)pBuf;
|
18079
18156
|
}
|
18080
|
-
return (void*)pBuf;
|
18081
18157
|
}
|
18082
18158
|
}
|
18083
18159
|
#else
|
@@ -18989,6 +19065,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
|
18989
19065
|
return;
|
18990
19066
|
}
|
18991
19067
|
}else{
|
19068
|
+
char *zOld = (p->zText==p->zBase ? 0 : p->zText);
|
18992
19069
|
i64 szNew = p->nChar;
|
18993
19070
|
szNew += N + 1;
|
18994
19071
|
if( szNew > p->mxAlloc ){
|
@@ -18999,13 +19076,12 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
|
|
18999
19076
|
p->nAlloc = (int)szNew;
|
19000
19077
|
}
|
19001
19078
|
if( p->useMalloc==1 ){
|
19002
|
-
zNew =
|
19079
|
+
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
|
19003
19080
|
}else{
|
19004
|
-
zNew =
|
19081
|
+
zNew = sqlite3_realloc(zOld, p->nAlloc);
|
19005
19082
|
}
|
19006
19083
|
if( zNew ){
|
19007
|
-
memcpy(zNew, p->zText, p->nChar);
|
19008
|
-
sqlite3StrAccumReset(p);
|
19084
|
+
if( zOld==0 ) memcpy(zNew, p->zText, p->nChar);
|
19009
19085
|
p->zText = zNew;
|
19010
19086
|
}else{
|
19011
19087
|
p->mallocFailed = 1;
|
@@ -19160,21 +19236,28 @@ SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
|
|
19160
19236
|
** current locale settings. This is important for SQLite because we
|
19161
19237
|
** are not able to use a "," as the decimal point in place of "." as
|
19162
19238
|
** specified by some locales.
|
19239
|
+
**
|
19240
|
+
** Oops: The first two arguments of sqlite3_snprintf() are backwards
|
19241
|
+
** from the snprintf() standard. Unfortunately, it is too late to change
|
19242
|
+
** this without breaking compatibility, so we just have to live with the
|
19243
|
+
** mistake.
|
19244
|
+
**
|
19245
|
+
** sqlite3_vsnprintf() is the varargs version.
|
19163
19246
|
*/
|
19164
|
-
SQLITE_API char *
|
19165
|
-
char *z;
|
19166
|
-
va_list ap;
|
19247
|
+
SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
|
19167
19248
|
StrAccum acc;
|
19168
|
-
|
19169
|
-
if( n<=0 ){
|
19170
|
-
return zBuf;
|
19171
|
-
}
|
19249
|
+
if( n<=0 ) return zBuf;
|
19172
19250
|
sqlite3StrAccumInit(&acc, zBuf, n, 0);
|
19173
19251
|
acc.useMalloc = 0;
|
19174
|
-
va_start(ap,zFormat);
|
19175
19252
|
sqlite3VXPrintf(&acc, 0, zFormat, ap);
|
19253
|
+
return sqlite3StrAccumFinish(&acc);
|
19254
|
+
}
|
19255
|
+
SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
|
19256
|
+
char *z;
|
19257
|
+
va_list ap;
|
19258
|
+
va_start(ap,zFormat);
|
19259
|
+
z = sqlite3_vsnprintf(n, zBuf, zFormat, ap);
|
19176
19260
|
va_end(ap);
|
19177
|
-
z = sqlite3StrAccumFinish(&acc);
|
19178
19261
|
return z;
|
19179
19262
|
}
|
19180
19263
|
|
@@ -22189,7 +22272,7 @@ static int os2FileControl(sqlite3_file *id, int op, void *pArg){
|
|
22189
22272
|
return SQLITE_OK;
|
22190
22273
|
}
|
22191
22274
|
}
|
22192
|
-
return
|
22275
|
+
return SQLITE_NOTFOUND;
|
22193
22276
|
}
|
22194
22277
|
|
22195
22278
|
/*
|
@@ -22905,7 +22988,9 @@ SQLITE_API int sqlite3_os_end(void){
|
|
22905
22988
|
#include <unistd.h>
|
22906
22989
|
#include <sys/time.h>
|
22907
22990
|
#include <errno.h>
|
22991
|
+
#ifndef SQLITE_OMIT_WAL
|
22908
22992
|
#include <sys/mman.h>
|
22993
|
+
#endif
|
22909
22994
|
|
22910
22995
|
#if SQLITE_ENABLE_LOCKING_STYLE
|
22911
22996
|
# include <sys/ioctl.h>
|
@@ -26123,8 +26208,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
|
26123
26208
|
return proxyFileControl(id,op,pArg);
|
26124
26209
|
}
|
26125
26210
|
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
|
26211
|
+
case SQLITE_FCNTL_SYNC_OMITTED: {
|
26212
|
+
return SQLITE_OK; /* A no-op */
|
26213
|
+
}
|
26126
26214
|
}
|
26127
|
-
return
|
26215
|
+
return SQLITE_NOTFOUND;
|
26128
26216
|
}
|
26129
26217
|
|
26130
26218
|
/*
|
@@ -28393,18 +28481,19 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
|
|
28393
28481
|
** bytes of writable memory.
|
28394
28482
|
*/
|
28395
28483
|
static int proxyGetHostID(unsigned char *pHostID, int *pError){
|
28396
|
-
struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
28397
|
-
|
28398
28484
|
assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
|
28399
28485
|
memset(pHostID, 0, PROXY_HOSTIDLEN);
|
28400
28486
|
#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\
|
28401
28487
|
&& __MAC_OS_X_VERSION_MIN_REQUIRED<1050
|
28402
|
-
|
28403
|
-
|
28404
|
-
if(
|
28405
|
-
|
28488
|
+
{
|
28489
|
+
static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
|
28490
|
+
if( gethostuuid(pHostID, &timeout) ){
|
28491
|
+
int err = errno;
|
28492
|
+
if( pError ){
|
28493
|
+
*pError = err;
|
28494
|
+
}
|
28495
|
+
return SQLITE_IOERR;
|
28406
28496
|
}
|
28407
|
-
return SQLITE_IOERR;
|
28408
28497
|
}
|
28409
28498
|
#endif
|
28410
28499
|
#ifdef SQLITE_TEST
|
@@ -30710,8 +30799,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
|
|
30710
30799
|
SimulateIOErrorBenign(0);
|
30711
30800
|
return SQLITE_OK;
|
30712
30801
|
}
|
30802
|
+
case SQLITE_FCNTL_SYNC_OMITTED: {
|
30803
|
+
return SQLITE_OK;
|
30804
|
+
}
|
30713
30805
|
}
|
30714
|
-
return
|
30806
|
+
return SQLITE_NOTFOUND;
|
30715
30807
|
}
|
30716
30808
|
|
30717
30809
|
/*
|
@@ -33331,6 +33423,38 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd
|
|
33331
33423
|
typedef struct PCache1 PCache1;
|
33332
33424
|
typedef struct PgHdr1 PgHdr1;
|
33333
33425
|
typedef struct PgFreeslot PgFreeslot;
|
33426
|
+
typedef struct PGroup PGroup;
|
33427
|
+
|
33428
|
+
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
|
33429
|
+
** of one or more PCaches that are able to recycle each others unpinned
|
33430
|
+
** pages when they are under memory pressure. A PGroup is an instance of
|
33431
|
+
** the following object.
|
33432
|
+
**
|
33433
|
+
** This page cache implementation works in one of two modes:
|
33434
|
+
**
|
33435
|
+
** (1) Every PCache is the sole member of its own PGroup. There is
|
33436
|
+
** one PGroup per PCache.
|
33437
|
+
**
|
33438
|
+
** (2) There is a single global PGroup that all PCaches are a member
|
33439
|
+
** of.
|
33440
|
+
**
|
33441
|
+
** Mode 1 uses more memory (since PCache instances are not able to rob
|
33442
|
+
** unused pages from other PCaches) but it also operates without a mutex,
|
33443
|
+
** and is therefore often faster. Mode 2 requires a mutex in order to be
|
33444
|
+
** threadsafe, but is able recycle pages more efficient.
|
33445
|
+
**
|
33446
|
+
** For mode (1), PGroup.mutex is NULL. For mode (2) there is only a single
|
33447
|
+
** PGroup which is the pcache1.grp global variable and its mutex is
|
33448
|
+
** SQLITE_MUTEX_STATIC_LRU.
|
33449
|
+
*/
|
33450
|
+
struct PGroup {
|
33451
|
+
sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */
|
33452
|
+
int nMaxPage; /* Sum of nMax for purgeable caches */
|
33453
|
+
int nMinPage; /* Sum of nMin for purgeable caches */
|
33454
|
+
int mxPinned; /* nMaxpage + 10 - nMinPage */
|
33455
|
+
int nCurrentPage; /* Number of purgeable pages allocated */
|
33456
|
+
PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
|
33457
|
+
};
|
33334
33458
|
|
33335
33459
|
/* Each page cache is an instance of the following object. Every
|
33336
33460
|
** open database file (including each in-memory database and each
|
@@ -33344,16 +33468,17 @@ struct PCache1 {
|
|
33344
33468
|
/* Cache configuration parameters. Page size (szPage) and the purgeable
|
33345
33469
|
** flag (bPurgeable) are set when the cache is created. nMax may be
|
33346
33470
|
** modified at any time by a call to the pcache1CacheSize() method.
|
33347
|
-
** The
|
33471
|
+
** The PGroup mutex must be held when accessing nMax.
|
33348
33472
|
*/
|
33473
|
+
PGroup *pGroup; /* PGroup this cache belongs to */
|
33349
33474
|
int szPage; /* Size of allocated pages in bytes */
|
33350
33475
|
int bPurgeable; /* True if cache is purgeable */
|
33351
33476
|
unsigned int nMin; /* Minimum number of pages reserved */
|
33352
33477
|
unsigned int nMax; /* Configured "cache_size" value */
|
33478
|
+
unsigned int n90pct; /* nMax*9/10 */
|
33353
33479
|
|
33354
33480
|
/* Hash table of all pages. The following variables may only be accessed
|
33355
|
-
** when the accessor is holding the
|
33356
|
-
** and pcache1LeaveMutex()).
|
33481
|
+
** when the accessor is holding the PGroup mutex.
|
33357
33482
|
*/
|
33358
33483
|
unsigned int nRecyclable; /* Number of pages in the LRU list */
|
33359
33484
|
unsigned int nPage; /* Total number of pages in apHash */
|
@@ -33389,21 +33514,27 @@ struct PgFreeslot {
|
|
33389
33514
|
** Global data used by this cache.
|
33390
33515
|
*/
|
33391
33516
|
static SQLITE_WSD struct PCacheGlobal {
|
33392
|
-
|
33393
|
-
|
33394
|
-
|
33395
|
-
|
33396
|
-
|
33397
|
-
|
33398
|
-
|
33399
|
-
/*
|
33400
|
-
int szSlot;
|
33401
|
-
int nSlot;
|
33402
|
-
int
|
33403
|
-
|
33404
|
-
|
33405
|
-
|
33406
|
-
int
|
33517
|
+
PGroup grp; /* The global PGroup for mode (2) */
|
33518
|
+
|
33519
|
+
/* Variables related to SQLITE_CONFIG_PAGECACHE settings. The
|
33520
|
+
** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all
|
33521
|
+
** fixed at sqlite3_initialize() time and do not require mutex protection.
|
33522
|
+
** The nFreeSlot and pFree values do require mutex protection.
|
33523
|
+
*/
|
33524
|
+
int isInit; /* True if initialized */
|
33525
|
+
int szSlot; /* Size of each free slot */
|
33526
|
+
int nSlot; /* The number of pcache slots */
|
33527
|
+
int nReserve; /* Try to keep nFreeSlot above this */
|
33528
|
+
void *pStart, *pEnd; /* Bounds of pagecache malloc range */
|
33529
|
+
/* Above requires no mutex. Use mutex below for variable that follow. */
|
33530
|
+
sqlite3_mutex *mutex; /* Mutex for accessing the following: */
|
33531
|
+
int nFreeSlot; /* Number of unused pcache slots */
|
33532
|
+
PgFreeslot *pFree; /* Free page blocks */
|
33533
|
+
/* The following value requires a mutex to change. We skip the mutex on
|
33534
|
+
** reading because (1) most platforms read a 32-bit integer atomically and
|
33535
|
+
** (2) even if an incorrect value is read, no great harm is done since this
|
33536
|
+
** is really just an optimization. */
|
33537
|
+
int bUnderPressure; /* True if low on PAGECACHE memory */
|
33407
33538
|
} pcache1_g;
|
33408
33539
|
|
33409
33540
|
/*
|
@@ -33429,10 +33560,10 @@ static SQLITE_WSD struct PCacheGlobal {
|
|
33429
33560
|
#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
|
33430
33561
|
|
33431
33562
|
/*
|
33432
|
-
** Macros to enter and leave the
|
33563
|
+
** Macros to enter and leave the PCache LRU mutex.
|
33433
33564
|
*/
|
33434
|
-
#define pcache1EnterMutex() sqlite3_mutex_enter(
|
33435
|
-
#define pcache1LeaveMutex() sqlite3_mutex_leave(
|
33565
|
+
#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
|
33566
|
+
#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
|
33436
33567
|
|
33437
33568
|
/******************************************************************************/
|
33438
33569
|
/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
|
@@ -33442,6 +33573,9 @@ static SQLITE_WSD struct PCacheGlobal {
|
|
33442
33573
|
** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
|
33443
33574
|
** verb to sqlite3_config(). Parameter pBuf points to an allocation large
|
33444
33575
|
** enough to contain 'n' buffers of 'sz' bytes each.
|
33576
|
+
**
|
33577
|
+
** This routine is called from sqlite3_initialize() and so it is guaranteed
|
33578
|
+
** to be serialized already. There is no need for further mutexing.
|
33445
33579
|
*/
|
33446
33580
|
SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
|
33447
33581
|
if( pcache1.isInit ){
|
@@ -33452,6 +33586,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
|
|
33452
33586
|
pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
|
33453
33587
|
pcache1.pStart = pBuf;
|
33454
33588
|
pcache1.pFree = 0;
|
33589
|
+
pcache1.bUnderPressure = 0;
|
33455
33590
|
while( n-- ){
|
33456
33591
|
p = (PgFreeslot*)pBuf;
|
33457
33592
|
p->pNext = pcache1.pFree;
|
@@ -33467,32 +33602,36 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
|
|
33467
33602
|
** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no
|
33468
33603
|
** such buffer exists or there is no space left in it, this function falls
|
33469
33604
|
** back to sqlite3Malloc().
|
33605
|
+
**
|
33606
|
+
** Multiple threads can run this routine at the same time. Global variables
|
33607
|
+
** in pcache1 need to be protected via mutex.
|
33470
33608
|
*/
|
33471
33609
|
static void *pcache1Alloc(int nByte){
|
33472
|
-
void *p;
|
33473
|
-
assert(
|
33610
|
+
void *p = 0;
|
33611
|
+
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
|
33474
33612
|
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
|
33475
|
-
if( nByte<=pcache1.szSlot
|
33476
|
-
|
33613
|
+
if( nByte<=pcache1.szSlot ){
|
33614
|
+
sqlite3_mutex_enter(pcache1.mutex);
|
33477
33615
|
p = (PgHdr1 *)pcache1.pFree;
|
33478
|
-
|
33479
|
-
|
33480
|
-
|
33481
|
-
|
33482
|
-
|
33483
|
-
|
33484
|
-
|
33485
|
-
|
33486
|
-
|
33487
|
-
|
33488
|
-
|
33616
|
+
if( p ){
|
33617
|
+
pcache1.pFree = pcache1.pFree->pNext;
|
33618
|
+
pcache1.nFreeSlot--;
|
33619
|
+
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
|
33620
|
+
assert( pcache1.nFreeSlot>=0 );
|
33621
|
+
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
|
33622
|
+
}
|
33623
|
+
sqlite3_mutex_leave(pcache1.mutex);
|
33624
|
+
}
|
33625
|
+
if( p==0 ){
|
33626
|
+
/* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get
|
33627
|
+
** it from sqlite3Malloc instead.
|
33489
33628
|
*/
|
33490
|
-
pcache1LeaveMutex();
|
33491
33629
|
p = sqlite3Malloc(nByte);
|
33492
|
-
pcache1EnterMutex();
|
33493
33630
|
if( p ){
|
33494
33631
|
int sz = sqlite3MallocSize(p);
|
33632
|
+
sqlite3_mutex_enter(pcache1.mutex);
|
33495
33633
|
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
|
33634
|
+
sqlite3_mutex_leave(pcache1.mutex);
|
33496
33635
|
}
|
33497
33636
|
sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
|
33498
33637
|
}
|
@@ -33503,22 +33642,26 @@ static void *pcache1Alloc(int nByte){
|
|
33503
33642
|
** Free an allocated buffer obtained from pcache1Alloc().
|
33504
33643
|
*/
|
33505
33644
|
static void pcache1Free(void *p){
|
33506
|
-
assert( sqlite3_mutex_held(pcache1.mutex) );
|
33507
33645
|
if( p==0 ) return;
|
33508
33646
|
if( p>=pcache1.pStart && p<pcache1.pEnd ){
|
33509
33647
|
PgFreeslot *pSlot;
|
33648
|
+
sqlite3_mutex_enter(pcache1.mutex);
|
33510
33649
|
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
|
33511
33650
|
pSlot = (PgFreeslot*)p;
|
33512
33651
|
pSlot->pNext = pcache1.pFree;
|
33513
33652
|
pcache1.pFree = pSlot;
|
33514
33653
|
pcache1.nFreeSlot++;
|
33654
|
+
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
|
33515
33655
|
assert( pcache1.nFreeSlot<=pcache1.nSlot );
|
33656
|
+
sqlite3_mutex_leave(pcache1.mutex);
|
33516
33657
|
}else{
|
33517
33658
|
int iSize;
|
33518
33659
|
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
|
33519
33660
|
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
|
33520
33661
|
iSize = sqlite3MallocSize(p);
|
33662
|
+
sqlite3_mutex_enter(pcache1.mutex);
|
33521
33663
|
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
|
33664
|
+
sqlite3_mutex_leave(pcache1.mutex);
|
33522
33665
|
sqlite3_free(p);
|
33523
33666
|
}
|
33524
33667
|
}
|
@@ -33528,7 +33671,6 @@ static void pcache1Free(void *p){
|
|
33528
33671
|
** Return the size of a pcache allocation
|
33529
33672
|
*/
|
33530
33673
|
static int pcache1MemSize(void *p){
|
33531
|
-
assert( sqlite3_mutex_held(pcache1.mutex) );
|
33532
33674
|
if( p>=pcache1.pStart && p<pcache1.pEnd ){
|
33533
33675
|
return pcache1.szSlot;
|
33534
33676
|
}else{
|
@@ -33552,7 +33694,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
|
33552
33694
|
if( pPg ){
|
33553
33695
|
p = PAGE_TO_PGHDR1(pCache, pPg);
|
33554
33696
|
if( pCache->bPurgeable ){
|
33555
|
-
|
33697
|
+
pCache->pGroup->nCurrentPage++;
|
33556
33698
|
}
|
33557
33699
|
}else{
|
33558
33700
|
p = 0;
|
@@ -33569,8 +33711,9 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
|
|
33569
33711
|
*/
|
33570
33712
|
static void pcache1FreePage(PgHdr1 *p){
|
33571
33713
|
if( ALWAYS(p) ){
|
33572
|
-
|
33573
|
-
|
33714
|
+
PCache1 *pCache = p->pCache;
|
33715
|
+
if( pCache->bPurgeable ){
|
33716
|
+
pCache->pGroup->nCurrentPage--;
|
33574
33717
|
}
|
33575
33718
|
pcache1Free(PGHDR1_TO_PAGE(p));
|
33576
33719
|
}
|
@@ -33582,20 +33725,14 @@ static void pcache1FreePage(PgHdr1 *p){
|
|
33582
33725
|
** exists, this function falls back to sqlite3Malloc().
|
33583
33726
|
*/
|
33584
33727
|
SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
|
33585
|
-
|
33586
|
-
pcache1EnterMutex();
|
33587
|
-
p = pcache1Alloc(sz);
|
33588
|
-
pcache1LeaveMutex();
|
33589
|
-
return p;
|
33728
|
+
return pcache1Alloc(sz);
|
33590
33729
|
}
|
33591
33730
|
|
33592
33731
|
/*
|
33593
33732
|
** Free an allocated buffer obtained from sqlite3PageMalloc().
|
33594
33733
|
*/
|
33595
33734
|
SQLITE_PRIVATE void sqlite3PageFree(void *p){
|
33596
|
-
pcache1EnterMutex();
|
33597
33735
|
pcache1Free(p);
|
33598
|
-
pcache1LeaveMutex();
|
33599
33736
|
}
|
33600
33737
|
|
33601
33738
|
|
@@ -33616,9 +33753,8 @@ SQLITE_PRIVATE void sqlite3PageFree(void *p){
|
|
33616
33753
|
** the heap even further.
|
33617
33754
|
*/
|
33618
33755
|
static int pcache1UnderMemoryPressure(PCache1 *pCache){
|
33619
|
-
assert( sqlite3_mutex_held(pcache1.mutex) );
|
33620
33756
|
if( pcache1.nSlot && pCache->szPage<=pcache1.szSlot ){
|
33621
|
-
return pcache1.
|
33757
|
+
return pcache1.bUnderPressure;
|
33622
33758
|
}else{
|
33623
33759
|
return sqlite3HeapNearlyFull();
|
33624
33760
|
}
|
@@ -33631,25 +33767,25 @@ static int pcache1UnderMemoryPressure(PCache1 *pCache){
|
|
33631
33767
|
** This function is used to resize the hash table used by the cache passed
|
33632
33768
|
** as the first argument.
|
33633
33769
|
**
|
33634
|
-
** The
|
33770
|
+
** The PCache mutex must be held when this function is called.
|
33635
33771
|
*/
|
33636
33772
|
static int pcache1ResizeHash(PCache1 *p){
|
33637
33773
|
PgHdr1 **apNew;
|
33638
33774
|
unsigned int nNew;
|
33639
33775
|
unsigned int i;
|
33640
33776
|
|
33641
|
-
assert( sqlite3_mutex_held(
|
33777
|
+
assert( sqlite3_mutex_held(p->pGroup->mutex) );
|
33642
33778
|
|
33643
33779
|
nNew = p->nHash*2;
|
33644
33780
|
if( nNew<256 ){
|
33645
33781
|
nNew = 256;
|
33646
33782
|
}
|
33647
33783
|
|
33648
|
-
pcache1LeaveMutex();
|
33784
|
+
pcache1LeaveMutex(p->pGroup);
|
33649
33785
|
if( p->nHash ){ sqlite3BeginBenignMalloc(); }
|
33650
33786
|
apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew);
|
33651
33787
|
if( p->nHash ){ sqlite3EndBenignMalloc(); }
|
33652
|
-
pcache1EnterMutex();
|
33788
|
+
pcache1EnterMutex(p->pGroup);
|
33653
33789
|
if( apNew ){
|
33654
33790
|
memset(apNew, 0, sizeof(PgHdr1 *)*nNew);
|
33655
33791
|
for(i=0; i<p->nHash; i++){
|
@@ -33672,25 +33808,33 @@ static int pcache1ResizeHash(PCache1 *p){
|
|
33672
33808
|
|
33673
33809
|
/*
|
33674
33810
|
** This function is used internally to remove the page pPage from the
|
33675
|
-
**
|
33811
|
+
** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
|
33676
33812
|
** LRU list, then this function is a no-op.
|
33677
33813
|
**
|
33678
|
-
** The
|
33814
|
+
** The PGroup mutex must be held when this function is called.
|
33815
|
+
**
|
33816
|
+
** If pPage is NULL then this routine is a no-op.
|
33679
33817
|
*/
|
33680
33818
|
static void pcache1PinPage(PgHdr1 *pPage){
|
33681
|
-
|
33682
|
-
|
33819
|
+
PCache1 *pCache;
|
33820
|
+
PGroup *pGroup;
|
33821
|
+
|
33822
|
+
if( pPage==0 ) return;
|
33823
|
+
pCache = pPage->pCache;
|
33824
|
+
pGroup = pCache->pGroup;
|
33825
|
+
assert( sqlite3_mutex_held(pGroup->mutex) );
|
33826
|
+
if( pPage->pLruNext || pPage==pGroup->pLruTail ){
|
33683
33827
|
if( pPage->pLruPrev ){
|
33684
33828
|
pPage->pLruPrev->pLruNext = pPage->pLruNext;
|
33685
33829
|
}
|
33686
33830
|
if( pPage->pLruNext ){
|
33687
33831
|
pPage->pLruNext->pLruPrev = pPage->pLruPrev;
|
33688
33832
|
}
|
33689
|
-
if(
|
33690
|
-
|
33833
|
+
if( pGroup->pLruHead==pPage ){
|
33834
|
+
pGroup->pLruHead = pPage->pLruNext;
|
33691
33835
|
}
|
33692
|
-
if(
|
33693
|
-
|
33836
|
+
if( pGroup->pLruTail==pPage ){
|
33837
|
+
pGroup->pLruTail = pPage->pLruPrev;
|
33694
33838
|
}
|
33695
33839
|
pPage->pLruNext = 0;
|
33696
33840
|
pPage->pLruPrev = 0;
|
@@ -33703,13 +33847,14 @@ static void pcache1PinPage(PgHdr1 *pPage){
|
|
33703
33847
|
** Remove the page supplied as an argument from the hash table
|
33704
33848
|
** (PCache1.apHash structure) that it is currently stored in.
|
33705
33849
|
**
|
33706
|
-
** The
|
33850
|
+
** The PGroup mutex must be held when this function is called.
|
33707
33851
|
*/
|
33708
33852
|
static void pcache1RemoveFromHash(PgHdr1 *pPage){
|
33709
33853
|
unsigned int h;
|
33710
33854
|
PCache1 *pCache = pPage->pCache;
|
33711
33855
|
PgHdr1 **pp;
|
33712
33856
|
|
33857
|
+
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
|
33713
33858
|
h = pPage->iKey % pCache->nHash;
|
33714
33859
|
for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext);
|
33715
33860
|
*pp = (*pp)->pNext;
|
@@ -33718,13 +33863,14 @@ static void pcache1RemoveFromHash(PgHdr1 *pPage){
|
|
33718
33863
|
}
|
33719
33864
|
|
33720
33865
|
/*
|
33721
|
-
** If there are currently more than
|
33722
|
-
** to recycle pages to reduce the number allocated to
|
33866
|
+
** If there are currently more than nMaxPage pages allocated, try
|
33867
|
+
** to recycle pages to reduce the number allocated to nMaxPage.
|
33723
33868
|
*/
|
33724
|
-
static void pcache1EnforceMaxPage(
|
33725
|
-
assert( sqlite3_mutex_held(
|
33726
|
-
while(
|
33727
|
-
PgHdr1 *p =
|
33869
|
+
static void pcache1EnforceMaxPage(PGroup *pGroup){
|
33870
|
+
assert( sqlite3_mutex_held(pGroup->mutex) );
|
33871
|
+
while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
|
33872
|
+
PgHdr1 *p = pGroup->pLruTail;
|
33873
|
+
assert( p->pCache->pGroup==pGroup );
|
33728
33874
|
pcache1PinPage(p);
|
33729
33875
|
pcache1RemoveFromHash(p);
|
33730
33876
|
pcache1FreePage(p);
|
@@ -33736,15 +33882,15 @@ static void pcache1EnforceMaxPage(void){
|
|
33736
33882
|
** greater than or equal to iLimit. Any pinned pages that meet this
|
33737
33883
|
** criteria are unpinned before they are discarded.
|
33738
33884
|
**
|
33739
|
-
** The
|
33885
|
+
** The PCache mutex must be held when this function is called.
|
33740
33886
|
*/
|
33741
33887
|
static void pcache1TruncateUnsafe(
|
33742
|
-
PCache1 *pCache,
|
33743
|
-
unsigned int iLimit
|
33888
|
+
PCache1 *pCache, /* The cache to truncate */
|
33889
|
+
unsigned int iLimit /* Drop pages with this pgno or larger */
|
33744
33890
|
){
|
33745
|
-
TESTONLY( unsigned int nPage = 0; )
|
33891
|
+
TESTONLY( unsigned int nPage = 0; ) /* To assert pCache->nPage is correct */
|
33746
33892
|
unsigned int h;
|
33747
|
-
assert( sqlite3_mutex_held(
|
33893
|
+
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
|
33748
33894
|
for(h=0; h<pCache->nHash; h++){
|
33749
33895
|
PgHdr1 **pp = &pCache->apHash[h];
|
33750
33896
|
PgHdr1 *pPage;
|
@@ -33774,8 +33920,10 @@ static int pcache1Init(void *NotUsed){
|
|
33774
33920
|
assert( pcache1.isInit==0 );
|
33775
33921
|
memset(&pcache1, 0, sizeof(pcache1));
|
33776
33922
|
if( sqlite3GlobalConfig.bCoreMutex ){
|
33777
|
-
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
|
33923
|
+
pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
|
33924
|
+
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
|
33778
33925
|
}
|
33926
|
+
pcache1.grp.mxPinned = 10;
|
33779
33927
|
pcache1.isInit = 1;
|
33780
33928
|
return SQLITE_OK;
|
33781
33929
|
}
|
@@ -33797,18 +33945,47 @@ static void pcache1Shutdown(void *NotUsed){
|
|
33797
33945
|
** Allocate a new cache.
|
33798
33946
|
*/
|
33799
33947
|
static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
|
33800
|
-
PCache1 *pCache;
|
33948
|
+
PCache1 *pCache; /* The newly created page cache */
|
33949
|
+
PGroup *pGroup; /* The group the new page cache will belong to */
|
33950
|
+
int sz; /* Bytes of memory required to allocate the new cache */
|
33801
33951
|
|
33802
|
-
|
33952
|
+
/*
|
33953
|
+
** The seperateCache variable is true if each PCache has its own private
|
33954
|
+
** PGroup. In other words, separateCache is true for mode (1) where no
|
33955
|
+
** mutexing is required.
|
33956
|
+
**
|
33957
|
+
** * Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
|
33958
|
+
**
|
33959
|
+
** * Always use a unified cache in single-threaded applications
|
33960
|
+
**
|
33961
|
+
** * Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
|
33962
|
+
** use separate caches (mode-1)
|
33963
|
+
*/
|
33964
|
+
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
|
33965
|
+
const int separateCache = 0;
|
33966
|
+
#else
|
33967
|
+
int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
|
33968
|
+
#endif
|
33969
|
+
|
33970
|
+
sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
|
33971
|
+
pCache = (PCache1 *)sqlite3_malloc(sz);
|
33803
33972
|
if( pCache ){
|
33804
|
-
memset(pCache, 0,
|
33973
|
+
memset(pCache, 0, sz);
|
33974
|
+
if( separateCache ){
|
33975
|
+
pGroup = (PGroup*)&pCache[1];
|
33976
|
+
pGroup->mxPinned = 10;
|
33977
|
+
}else{
|
33978
|
+
pGroup = &pcache1_g.grp;
|
33979
|
+
}
|
33980
|
+
pCache->pGroup = pGroup;
|
33805
33981
|
pCache->szPage = szPage;
|
33806
33982
|
pCache->bPurgeable = (bPurgeable ? 1 : 0);
|
33807
33983
|
if( bPurgeable ){
|
33808
33984
|
pCache->nMin = 10;
|
33809
|
-
pcache1EnterMutex();
|
33810
|
-
|
33811
|
-
|
33985
|
+
pcache1EnterMutex(pGroup);
|
33986
|
+
pGroup->nMinPage += pCache->nMin;
|
33987
|
+
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
|
33988
|
+
pcache1LeaveMutex(pGroup);
|
33812
33989
|
}
|
33813
33990
|
}
|
33814
33991
|
return (sqlite3_pcache *)pCache;
|
@@ -33822,11 +33999,14 @@ static sqlite3_pcache *pcache1Create(int szPage, int bPurgeable){
|
|
33822
33999
|
static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
|
33823
34000
|
PCache1 *pCache = (PCache1 *)p;
|
33824
34001
|
if( pCache->bPurgeable ){
|
33825
|
-
|
33826
|
-
|
34002
|
+
PGroup *pGroup = pCache->pGroup;
|
34003
|
+
pcache1EnterMutex(pGroup);
|
34004
|
+
pGroup->nMaxPage += (nMax - pCache->nMax);
|
34005
|
+
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
|
33827
34006
|
pCache->nMax = nMax;
|
33828
|
-
|
33829
|
-
|
34007
|
+
pCache->n90pct = pCache->nMax*9/10;
|
34008
|
+
pcache1EnforceMaxPage(pGroup);
|
34009
|
+
pcache1LeaveMutex(pGroup);
|
33830
34010
|
}
|
33831
34011
|
}
|
33832
34012
|
|
@@ -33835,9 +34015,10 @@ static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
|
|
33835
34015
|
*/
|
33836
34016
|
static int pcache1Pagecount(sqlite3_pcache *p){
|
33837
34017
|
int n;
|
33838
|
-
|
33839
|
-
|
33840
|
-
|
34018
|
+
PCache1 *pCache = (PCache1*)p;
|
34019
|
+
pcache1EnterMutex(pCache->pGroup);
|
34020
|
+
n = pCache->nPage;
|
34021
|
+
pcache1LeaveMutex(pCache->pGroup);
|
33841
34022
|
return n;
|
33842
34023
|
}
|
33843
34024
|
|
@@ -33896,30 +34077,49 @@ static int pcache1Pagecount(sqlite3_pcache *p){
|
|
33896
34077
|
** 5. Otherwise, allocate and return a new page buffer.
|
33897
34078
|
*/
|
33898
34079
|
static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
33899
|
-
|
34080
|
+
int nPinned;
|
33900
34081
|
PCache1 *pCache = (PCache1 *)p;
|
34082
|
+
PGroup *pGroup;
|
33901
34083
|
PgHdr1 *pPage = 0;
|
33902
34084
|
|
33903
34085
|
assert( pCache->bPurgeable || createFlag!=1 );
|
33904
|
-
|
33905
|
-
|
34086
|
+
assert( pCache->bPurgeable || pCache->nMin==0 );
|
34087
|
+
assert( pCache->bPurgeable==0 || pCache->nMin==10 );
|
34088
|
+
assert( pCache->nMin==0 || pCache->bPurgeable );
|
34089
|
+
pcache1EnterMutex(pGroup = pCache->pGroup);
|
33906
34090
|
|
33907
|
-
/* Search the hash table for an existing entry. */
|
34091
|
+
/* Step 1: Search the hash table for an existing entry. */
|
33908
34092
|
if( pCache->nHash>0 ){
|
33909
34093
|
unsigned int h = iKey % pCache->nHash;
|
33910
34094
|
for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
|
33911
34095
|
}
|
33912
34096
|
|
34097
|
+
/* Step 2: Abort if no existing page is found and createFlag is 0 */
|
33913
34098
|
if( pPage || createFlag==0 ){
|
33914
34099
|
pcache1PinPage(pPage);
|
33915
34100
|
goto fetch_out;
|
33916
34101
|
}
|
33917
34102
|
|
33918
|
-
/*
|
34103
|
+
/* The pGroup local variable will normally be initialized by the
|
34104
|
+
** pcache1EnterMutex() macro above. But if SQLITE_MUTEX_OMIT is defined,
|
34105
|
+
** then pcache1EnterMutex() is a no-op, so we have to initialize the
|
34106
|
+
** local variable here. Delaying the initialization of pGroup is an
|
34107
|
+
** optimization: The common case is to exit the module before reaching
|
34108
|
+
** this point.
|
34109
|
+
*/
|
34110
|
+
#ifdef SQLITE_MUTEX_OMIT
|
34111
|
+
pGroup = pCache->pGroup;
|
34112
|
+
#endif
|
34113
|
+
|
34114
|
+
|
34115
|
+
/* Step 3: Abort if createFlag is 1 but the cache is nearly full */
|
33919
34116
|
nPinned = pCache->nPage - pCache->nRecyclable;
|
34117
|
+
assert( nPinned>=0 );
|
34118
|
+
assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
|
34119
|
+
assert( pCache->n90pct == pCache->nMax*9/10 );
|
33920
34120
|
if( createFlag==1 && (
|
33921
|
-
nPinned>=
|
33922
|
-
|| nPinned>=(pCache->
|
34121
|
+
nPinned>=pGroup->mxPinned
|
34122
|
+
|| nPinned>=(int)pCache->n90pct
|
33923
34123
|
|| pcache1UnderMemoryPressure(pCache)
|
33924
34124
|
)){
|
33925
34125
|
goto fetch_out;
|
@@ -33929,20 +34129,22 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
|
33929
34129
|
goto fetch_out;
|
33930
34130
|
}
|
33931
34131
|
|
33932
|
-
/* Step 4. Try to recycle a page
|
33933
|
-
if( pCache->bPurgeable &&
|
34132
|
+
/* Step 4. Try to recycle a page. */
|
34133
|
+
if( pCache->bPurgeable && pGroup->pLruTail && (
|
33934
34134
|
(pCache->nPage+1>=pCache->nMax)
|
33935
|
-
||
|
34135
|
+
|| pGroup->nCurrentPage>=pGroup->nMaxPage
|
33936
34136
|
|| pcache1UnderMemoryPressure(pCache)
|
33937
34137
|
)){
|
33938
|
-
|
34138
|
+
PCache1 *pOtherCache;
|
34139
|
+
pPage = pGroup->pLruTail;
|
33939
34140
|
pcache1RemoveFromHash(pPage);
|
33940
34141
|
pcache1PinPage(pPage);
|
33941
|
-
if( pPage->pCache->szPage!=pCache->szPage ){
|
34142
|
+
if( (pOtherCache = pPage->pCache)->szPage!=pCache->szPage ){
|
33942
34143
|
pcache1FreePage(pPage);
|
33943
34144
|
pPage = 0;
|
33944
34145
|
}else{
|
33945
|
-
|
34146
|
+
pGroup->nCurrentPage -=
|
34147
|
+
(pOtherCache->bPurgeable - pCache->bPurgeable);
|
33946
34148
|
}
|
33947
34149
|
}
|
33948
34150
|
|
@@ -33950,7 +34152,11 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
|
|
33950
34152
|
** attempt to allocate a new one.
|
33951
34153
|
*/
|
33952
34154
|
if( !pPage ){
|
34155
|
+
if( createFlag==1 ) sqlite3BeginBenignMalloc();
|
34156
|
+
pcache1LeaveMutex(pGroup);
|
33953
34157
|
pPage = pcache1AllocPage(pCache);
|
34158
|
+
pcache1EnterMutex(pGroup);
|
34159
|
+
if( createFlag==1 ) sqlite3EndBenignMalloc();
|
33954
34160
|
}
|
33955
34161
|
|
33956
34162
|
if( pPage ){
|
@@ -33969,8 +34175,7 @@ fetch_out:
|
|
33969
34175
|
if( pPage && iKey>pCache->iMaxKey ){
|
33970
34176
|
pCache->iMaxKey = iKey;
|
33971
34177
|
}
|
33972
|
-
|
33973
|
-
pcache1LeaveMutex();
|
34178
|
+
pcache1LeaveMutex(pGroup);
|
33974
34179
|
return (pPage ? PGHDR1_TO_PAGE(pPage) : 0);
|
33975
34180
|
}
|
33976
34181
|
|
@@ -33983,37 +34188,34 @@ fetch_out:
|
|
33983
34188
|
static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
|
33984
34189
|
PCache1 *pCache = (PCache1 *)p;
|
33985
34190
|
PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
|
34191
|
+
PGroup *pGroup = pCache->pGroup;
|
33986
34192
|
|
33987
34193
|
assert( pPage->pCache==pCache );
|
33988
|
-
pcache1EnterMutex();
|
34194
|
+
pcache1EnterMutex(pGroup);
|
33989
34195
|
|
33990
34196
|
/* It is an error to call this function if the page is already
|
33991
|
-
** part of the
|
34197
|
+
** part of the PGroup LRU list.
|
33992
34198
|
*/
|
33993
34199
|
assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
|
33994
|
-
assert(
|
34200
|
+
assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
|
33995
34201
|
|
33996
|
-
if( reuseUnlikely ||
|
34202
|
+
if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
|
33997
34203
|
pcache1RemoveFromHash(pPage);
|
33998
34204
|
pcache1FreePage(pPage);
|
33999
34205
|
}else{
|
34000
|
-
/* Add the page to the
|
34001
|
-
|
34002
|
-
|
34003
|
-
|
34004
|
-
|
34005
|
-
if( pcache1.pLruHead ){
|
34006
|
-
pcache1.pLruHead->pLruPrev = pPage;
|
34007
|
-
pPage->pLruNext = pcache1.pLruHead;
|
34008
|
-
pcache1.pLruHead = pPage;
|
34206
|
+
/* Add the page to the PGroup LRU list. */
|
34207
|
+
if( pGroup->pLruHead ){
|
34208
|
+
pGroup->pLruHead->pLruPrev = pPage;
|
34209
|
+
pPage->pLruNext = pGroup->pLruHead;
|
34210
|
+
pGroup->pLruHead = pPage;
|
34009
34211
|
}else{
|
34010
|
-
|
34011
|
-
|
34212
|
+
pGroup->pLruTail = pPage;
|
34213
|
+
pGroup->pLruHead = pPage;
|
34012
34214
|
}
|
34013
34215
|
pCache->nRecyclable++;
|
34014
34216
|
}
|
34015
34217
|
|
34016
|
-
pcache1LeaveMutex();
|
34218
|
+
pcache1LeaveMutex(pCache->pGroup);
|
34017
34219
|
}
|
34018
34220
|
|
34019
34221
|
/*
|
@@ -34032,7 +34234,7 @@ static void pcache1Rekey(
|
|
34032
34234
|
assert( pPage->iKey==iOld );
|
34033
34235
|
assert( pPage->pCache==pCache );
|
34034
34236
|
|
34035
|
-
pcache1EnterMutex();
|
34237
|
+
pcache1EnterMutex(pCache->pGroup);
|
34036
34238
|
|
34037
34239
|
h = iOld%pCache->nHash;
|
34038
34240
|
pp = &pCache->apHash[h];
|
@@ -34049,7 +34251,7 @@ static void pcache1Rekey(
|
|
34049
34251
|
pCache->iMaxKey = iNew;
|
34050
34252
|
}
|
34051
34253
|
|
34052
|
-
pcache1LeaveMutex();
|
34254
|
+
pcache1LeaveMutex(pCache->pGroup);
|
34053
34255
|
}
|
34054
34256
|
|
34055
34257
|
/*
|
@@ -34061,12 +34263,12 @@ static void pcache1Rekey(
|
|
34061
34263
|
*/
|
34062
34264
|
static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
|
34063
34265
|
PCache1 *pCache = (PCache1 *)p;
|
34064
|
-
pcache1EnterMutex();
|
34266
|
+
pcache1EnterMutex(pCache->pGroup);
|
34065
34267
|
if( iLimit<=pCache->iMaxKey ){
|
34066
34268
|
pcache1TruncateUnsafe(pCache, iLimit);
|
34067
34269
|
pCache->iMaxKey = iLimit-1;
|
34068
34270
|
}
|
34069
|
-
pcache1LeaveMutex();
|
34271
|
+
pcache1LeaveMutex(pCache->pGroup);
|
34070
34272
|
}
|
34071
34273
|
|
34072
34274
|
/*
|
@@ -34076,13 +34278,15 @@ static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
|
|
34076
34278
|
*/
|
34077
34279
|
static void pcache1Destroy(sqlite3_pcache *p){
|
34078
34280
|
PCache1 *pCache = (PCache1 *)p;
|
34281
|
+
PGroup *pGroup = pCache->pGroup;
|
34079
34282
|
assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
|
34080
|
-
pcache1EnterMutex();
|
34283
|
+
pcache1EnterMutex(pGroup);
|
34081
34284
|
pcache1TruncateUnsafe(pCache, 0);
|
34082
|
-
|
34083
|
-
|
34084
|
-
|
34085
|
-
|
34285
|
+
pGroup->nMaxPage -= pCache->nMax;
|
34286
|
+
pGroup->nMinPage -= pCache->nMin;
|
34287
|
+
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
|
34288
|
+
pcache1EnforceMaxPage(pGroup);
|
34289
|
+
pcache1LeaveMutex(pGroup);
|
34086
34290
|
sqlite3_free(pCache->apHash);
|
34087
34291
|
sqlite3_free(pCache);
|
34088
34292
|
}
|
@@ -34121,16 +34325,18 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
|
|
34121
34325
|
*/
|
34122
34326
|
SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
|
34123
34327
|
int nFree = 0;
|
34328
|
+
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
|
34329
|
+
assert( sqlite3_mutex_notheld(pcache1.mutex) );
|
34124
34330
|
if( pcache1.pStart==0 ){
|
34125
34331
|
PgHdr1 *p;
|
34126
|
-
pcache1EnterMutex();
|
34127
|
-
while( (nReq<0 || nFree<nReq) && ((p=pcache1.pLruTail)!=0) ){
|
34332
|
+
pcache1EnterMutex(&pcache1.grp);
|
34333
|
+
while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
|
34128
34334
|
nFree += pcache1MemSize(PGHDR1_TO_PAGE(p));
|
34129
34335
|
pcache1PinPage(p);
|
34130
34336
|
pcache1RemoveFromHash(p);
|
34131
34337
|
pcache1FreePage(p);
|
34132
34338
|
}
|
34133
|
-
pcache1LeaveMutex();
|
34339
|
+
pcache1LeaveMutex(&pcache1.grp);
|
34134
34340
|
}
|
34135
34341
|
return nFree;
|
34136
34342
|
}
|
@@ -34149,12 +34355,12 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
|
|
34149
34355
|
){
|
34150
34356
|
PgHdr1 *p;
|
34151
34357
|
int nRecyclable = 0;
|
34152
|
-
for(p=pcache1.pLruHead; p; p=p->pLruNext){
|
34358
|
+
for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
|
34153
34359
|
nRecyclable++;
|
34154
34360
|
}
|
34155
|
-
*pnCurrent = pcache1.nCurrentPage;
|
34156
|
-
*pnMax = pcache1.nMaxPage;
|
34157
|
-
*pnMin = pcache1.nMinPage;
|
34361
|
+
*pnCurrent = pcache1.grp.nCurrentPage;
|
34362
|
+
*pnMax = pcache1.grp.nMaxPage;
|
34363
|
+
*pnMin = pcache1.grp.nMinPage;
|
34158
34364
|
*pnRecyclable = nRecyclable;
|
34159
34365
|
}
|
34160
34366
|
#endif
|
@@ -37179,15 +37385,21 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
|
|
37179
37385
|
&& (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
|
37180
37386
|
){
|
37181
37387
|
i64 currentSize, newSize;
|
37388
|
+
int szPage = pPager->pageSize;
|
37182
37389
|
assert( pPager->eLock==EXCLUSIVE_LOCK );
|
37183
37390
|
/* TODO: Is it safe to use Pager.dbFileSize here? */
|
37184
37391
|
rc = sqlite3OsFileSize(pPager->fd, ¤tSize);
|
37185
|
-
newSize =
|
37392
|
+
newSize = szPage*(i64)nPage;
|
37186
37393
|
if( rc==SQLITE_OK && currentSize!=newSize ){
|
37187
37394
|
if( currentSize>newSize ){
|
37188
37395
|
rc = sqlite3OsTruncate(pPager->fd, newSize);
|
37189
37396
|
}else{
|
37190
|
-
|
37397
|
+
char *pTmp = pPager->pTmpSpace;
|
37398
|
+
memset(pTmp, 0, szPage);
|
37399
|
+
testcase( (newSize-szPage) < currentSize );
|
37400
|
+
testcase( (newSize-szPage) == currentSize );
|
37401
|
+
testcase( (newSize-szPage) > currentSize );
|
37402
|
+
rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
|
37191
37403
|
}
|
37192
37404
|
if( rc==SQLITE_OK ){
|
37193
37405
|
pPager->dbFileSize = nPage;
|
@@ -37451,10 +37663,10 @@ end_playback:
|
|
37451
37663
|
rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
|
37452
37664
|
testcase( rc!=SQLITE_OK );
|
37453
37665
|
}
|
37454
|
-
if( rc==SQLITE_OK
|
37666
|
+
if( rc==SQLITE_OK
|
37455
37667
|
&& (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
|
37456
37668
|
){
|
37457
|
-
rc =
|
37669
|
+
rc = sqlite3PagerSync(pPager);
|
37458
37670
|
}
|
37459
37671
|
if( rc==SQLITE_OK ){
|
37460
37672
|
rc = pager_end_transaction(pPager, zMaster[0]!='\0');
|
@@ -37617,11 +37829,37 @@ static int pagerRollbackWal(Pager *pPager){
|
|
37617
37829
|
return rc;
|
37618
37830
|
}
|
37619
37831
|
|
37832
|
+
|
37833
|
+
/*
|
37834
|
+
** Update the value of the change-counter at offsets 24 and 92 in
|
37835
|
+
** the header and the sqlite version number at offset 96.
|
37836
|
+
**
|
37837
|
+
** This is an unconditional update. See also the pager_incr_changecounter()
|
37838
|
+
** routine which only updates the change-counter if the update is actually
|
37839
|
+
** needed, as determined by the pPager->changeCountDone state variable.
|
37840
|
+
*/
|
37841
|
+
static void pager_write_changecounter(PgHdr *pPg){
|
37842
|
+
u32 change_counter;
|
37843
|
+
|
37844
|
+
/* Increment the value just read and write it back to byte 24. */
|
37845
|
+
change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
|
37846
|
+
put32bits(((char*)pPg->pData)+24, change_counter);
|
37847
|
+
|
37848
|
+
/* Also store the SQLite version number in bytes 96..99 and in
|
37849
|
+
** bytes 92..95 store the change counter for which the version number
|
37850
|
+
** is valid. */
|
37851
|
+
put32bits(((char*)pPg->pData)+92, change_counter);
|
37852
|
+
put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
|
37853
|
+
}
|
37854
|
+
|
37620
37855
|
/*
|
37621
37856
|
** This function is a wrapper around sqlite3WalFrames(). As well as logging
|
37622
37857
|
** the contents of the list of pages headed by pList (connected by pDirty),
|
37623
37858
|
** this function notifies any active backup processes that the pages have
|
37624
|
-
** changed.
|
37859
|
+
** changed.
|
37860
|
+
**
|
37861
|
+
** The list of pages passed into this routine is always sorted by page number.
|
37862
|
+
** Hence, if page 1 appears anywhere on the list, it will be the first page.
|
37625
37863
|
*/
|
37626
37864
|
static int pagerWalFrames(
|
37627
37865
|
Pager *pPager, /* Pager object */
|
@@ -37631,8 +37869,19 @@ static int pagerWalFrames(
|
|
37631
37869
|
int syncFlags /* Flags to pass to OsSync() (or 0) */
|
37632
37870
|
){
|
37633
37871
|
int rc; /* Return code */
|
37872
|
+
#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
|
37873
|
+
PgHdr *p; /* For looping over pages */
|
37874
|
+
#endif
|
37634
37875
|
|
37635
37876
|
assert( pPager->pWal );
|
37877
|
+
#ifdef SQLITE_DEBUG
|
37878
|
+
/* Verify that the page list is in accending order */
|
37879
|
+
for(p=pList; p && p->pDirty; p=p->pDirty){
|
37880
|
+
assert( p->pgno < p->pDirty->pgno );
|
37881
|
+
}
|
37882
|
+
#endif
|
37883
|
+
|
37884
|
+
if( pList->pgno==1 ) pager_write_changecounter(pList);
|
37636
37885
|
rc = sqlite3WalFrames(pPager->pWal,
|
37637
37886
|
pPager->pageSize, pList, nTruncate, isCommit, syncFlags
|
37638
37887
|
);
|
@@ -37644,9 +37893,8 @@ static int pagerWalFrames(
|
|
37644
37893
|
}
|
37645
37894
|
|
37646
37895
|
#ifdef SQLITE_CHECK_PAGES
|
37647
|
-
{
|
37648
|
-
|
37649
|
-
for(p=pList; p; p=p->pDirty) pager_set_pagehash(p);
|
37896
|
+
for(p=pList; p; p=p->pDirty){
|
37897
|
+
pager_set_pagehash(p);
|
37650
37898
|
}
|
37651
37899
|
#endif
|
37652
37900
|
|
@@ -38671,6 +38919,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
|
|
38671
38919
|
char *pData; /* Data to write */
|
38672
38920
|
|
38673
38921
|
assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
|
38922
|
+
if( pList->pgno==1 ) pager_write_changecounter(pList);
|
38674
38923
|
|
38675
38924
|
/* Encode the database */
|
38676
38925
|
CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
|
@@ -40191,7 +40440,13 @@ SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
|
|
40191
40440
|
/*
|
40192
40441
|
** This routine is called to increment the value of the database file
|
40193
40442
|
** change-counter, stored as a 4-byte big-endian integer starting at
|
40194
|
-
** byte offset 24 of the pager file.
|
40443
|
+
** byte offset 24 of the pager file. The secondary change counter at
|
40444
|
+
** 92 is also updated, as is the SQLite version number at offset 96.
|
40445
|
+
**
|
40446
|
+
** But this only happens if the pPager->changeCountDone flag is false.
|
40447
|
+
** To avoid excess churning of page 1, the update only happens once.
|
40448
|
+
** See also the pager_write_changecounter() routine that does an
|
40449
|
+
** unconditional update of the change counters.
|
40195
40450
|
**
|
40196
40451
|
** If the isDirectMode flag is zero, then this is done by calling
|
40197
40452
|
** sqlite3PagerWrite() on page 1, then modifying the contents of the
|
@@ -40232,7 +40487,6 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
|
|
40232
40487
|
|
40233
40488
|
if( !pPager->changeCountDone && pPager->dbSize>0 ){
|
40234
40489
|
PgHdr *pPgHdr; /* Reference to page 1 */
|
40235
|
-
u32 change_counter; /* Initial value of change-counter field */
|
40236
40490
|
|
40237
40491
|
assert( !pPager->tempFile && isOpen(pPager->fd) );
|
40238
40492
|
|
@@ -40250,16 +40504,8 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
|
|
40250
40504
|
}
|
40251
40505
|
|
40252
40506
|
if( rc==SQLITE_OK ){
|
40253
|
-
/*
|
40254
|
-
|
40255
|
-
change_counter++;
|
40256
|
-
put32bits(((char*)pPgHdr->pData)+24, change_counter);
|
40257
|
-
|
40258
|
-
/* Also store the SQLite version number in bytes 96..99 and in
|
40259
|
-
** bytes 92..95 store the change counter for which the version number
|
40260
|
-
** is valid. */
|
40261
|
-
put32bits(((char*)pPgHdr->pData)+92, change_counter);
|
40262
|
-
put32bits(((char*)pPgHdr->pData)+96, SQLITE_VERSION_NUMBER);
|
40507
|
+
/* Actually do the update of the change counter */
|
40508
|
+
pager_write_changecounter(pPgHdr);
|
40263
40509
|
|
40264
40510
|
/* If running in direct mode, write the contents of page 1 to the file. */
|
40265
40511
|
if( DIRECT_MODE ){
|
@@ -40291,12 +40537,13 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
|
|
40291
40537
|
** function returns SQLITE_OK. Otherwise, an IO error code is returned.
|
40292
40538
|
*/
|
40293
40539
|
SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){
|
40294
|
-
int rc
|
40295
|
-
|
40296
|
-
|
40297
|
-
rc = SQLITE_OK;
|
40298
|
-
}else{
|
40540
|
+
int rc = SQLITE_OK;
|
40541
|
+
if( !pPager->noSync ){
|
40542
|
+
assert( !MEMDB );
|
40299
40543
|
rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
|
40544
|
+
}else if( isOpen(pPager->fd) ){
|
40545
|
+
assert( !MEMDB );
|
40546
|
+
sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, (void *)&rc);
|
40300
40547
|
}
|
40301
40548
|
return rc;
|
40302
40549
|
}
|
@@ -40515,8 +40762,8 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
|
|
40515
40762
|
}
|
40516
40763
|
|
40517
40764
|
/* Finally, sync the database file. */
|
40518
|
-
if( !
|
40519
|
-
rc =
|
40765
|
+
if( !noSync ){
|
40766
|
+
rc = sqlite3PagerSync(pPager);
|
40520
40767
|
}
|
40521
40768
|
IOTRACE(("DBSYNC %p\n", pPager))
|
40522
40769
|
}
|
@@ -40628,7 +40875,17 @@ SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
|
|
40628
40875
|
rc2 = pager_end_transaction(pPager, pPager->setMaster);
|
40629
40876
|
if( rc==SQLITE_OK ) rc = rc2;
|
40630
40877
|
}else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
|
40878
|
+
int eState = pPager->eState;
|
40631
40879
|
rc = pager_end_transaction(pPager, 0);
|
40880
|
+
if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
|
40881
|
+
/* This can happen using journal_mode=off. Move the pager to the error
|
40882
|
+
** state to indicate that the contents of the cache may not be trusted.
|
40883
|
+
** Any active readers will get SQLITE_ABORT.
|
40884
|
+
*/
|
40885
|
+
pPager->errCode = SQLITE_ABORT;
|
40886
|
+
pPager->eState = PAGER_ERROR;
|
40887
|
+
return rc;
|
40888
|
+
}
|
40632
40889
|
}else{
|
40633
40890
|
rc = pager_playback(pPager, 0);
|
40634
40891
|
}
|
@@ -41898,14 +42155,14 @@ typedef u16 ht_slot;
|
|
41898
42155
|
*/
|
41899
42156
|
struct WalIterator {
|
41900
42157
|
int iPrior; /* Last result returned from the iterator */
|
41901
|
-
int nSegment; /*
|
42158
|
+
int nSegment; /* Number of entries in aSegment[] */
|
41902
42159
|
struct WalSegment {
|
41903
42160
|
int iNext; /* Next slot in aIndex[] not yet returned */
|
41904
42161
|
ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */
|
41905
42162
|
u32 *aPgno; /* Array of page numbers. */
|
41906
|
-
int nEntry; /*
|
42163
|
+
int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */
|
41907
42164
|
int iZero; /* Frame number associated with aPgno[0] */
|
41908
|
-
} aSegment[1]; /* One for every 32KB page in the
|
42165
|
+
} aSegment[1]; /* One for every 32KB page in the wal-index */
|
41909
42166
|
};
|
41910
42167
|
|
41911
42168
|
/*
|
@@ -42769,9 +43026,29 @@ static int walIteratorNext(
|
|
42769
43026
|
|
42770
43027
|
/*
|
42771
43028
|
** This function merges two sorted lists into a single sorted list.
|
43029
|
+
**
|
43030
|
+
** aLeft[] and aRight[] are arrays of indices. The sort key is
|
43031
|
+
** aContent[aLeft[]] and aContent[aRight[]]. Upon entry, the following
|
43032
|
+
** is guaranteed for all J<K:
|
43033
|
+
**
|
43034
|
+
** aContent[aLeft[J]] < aContent[aLeft[K]]
|
43035
|
+
** aContent[aRight[J]] < aContent[aRight[K]]
|
43036
|
+
**
|
43037
|
+
** This routine overwrites aRight[] with a new (probably longer) sequence
|
43038
|
+
** of indices such that the aRight[] contains every index that appears in
|
43039
|
+
** either aLeft[] or the old aRight[] and such that the second condition
|
43040
|
+
** above is still met.
|
43041
|
+
**
|
43042
|
+
** The aContent[aLeft[X]] values will be unique for all X. And the
|
43043
|
+
** aContent[aRight[X]] values will be unique too. But there might be
|
43044
|
+
** one or more combinations of X and Y such that
|
43045
|
+
**
|
43046
|
+
** aLeft[X]!=aRight[Y] && aContent[aLeft[X]] == aContent[aRight[Y]]
|
43047
|
+
**
|
43048
|
+
** When that happens, omit the aLeft[X] and use the aRight[Y] index.
|
42772
43049
|
*/
|
42773
43050
|
static void walMerge(
|
42774
|
-
u32 *aContent,
|
43051
|
+
const u32 *aContent, /* Pages in wal - keys for the sort */
|
42775
43052
|
ht_slot *aLeft, /* IN: Left hand input list */
|
42776
43053
|
int nLeft, /* IN: Elements in array *paLeft */
|
42777
43054
|
ht_slot **paRight, /* IN/OUT: Right hand input list */
|
@@ -42811,10 +43088,24 @@ static void walMerge(
|
|
42811
43088
|
}
|
42812
43089
|
|
42813
43090
|
/*
|
42814
|
-
** Sort the elements in list aList
|
43091
|
+
** Sort the elements in list aList using aContent[] as the sort key.
|
43092
|
+
** Remove elements with duplicate keys, preferring to keep the
|
43093
|
+
** larger aList[] values.
|
43094
|
+
**
|
43095
|
+
** The aList[] entries are indices into aContent[]. The values in
|
43096
|
+
** aList[] are to be sorted so that for all J<K:
|
43097
|
+
**
|
43098
|
+
** aContent[aList[J]] < aContent[aList[K]]
|
43099
|
+
**
|
43100
|
+
** For any X and Y such that
|
43101
|
+
**
|
43102
|
+
** aContent[aList[X]] == aContent[aList[Y]]
|
43103
|
+
**
|
43104
|
+
** Keep the larger of the two values aList[X] and aList[Y] and discard
|
43105
|
+
** the smaller.
|
42815
43106
|
*/
|
42816
43107
|
static void walMergesort(
|
42817
|
-
u32 *aContent,
|
43108
|
+
const u32 *aContent, /* Pages in wal */
|
42818
43109
|
ht_slot *aBuffer, /* Buffer of at least *pnList items to use */
|
42819
43110
|
ht_slot *aList, /* IN/OUT: List to sort */
|
42820
43111
|
int *pnList /* IN/OUT: Number of elements in aList[] */
|
@@ -42879,6 +43170,7 @@ static void walIteratorFree(WalIterator *p){
|
|
42879
43170
|
/*
|
42880
43171
|
** Construct a WalInterator object that can be used to loop over all
|
42881
43172
|
** pages in the WAL in ascending order. The caller must hold the checkpoint
|
43173
|
+
** lock.
|
42882
43174
|
**
|
42883
43175
|
** On success, make *pp point to the newly allocated WalInterator object
|
42884
43176
|
** return SQLITE_OK. Otherwise, return an error code. If this routine
|
@@ -43013,7 +43305,8 @@ static int walCheckpoint(
|
|
43013
43305
|
szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
|
43014
43306
|
testcase( szPage<=32768 );
|
43015
43307
|
testcase( szPage>=65536 );
|
43016
|
-
|
43308
|
+
pInfo = walCkptInfo(pWal);
|
43309
|
+
if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK;
|
43017
43310
|
|
43018
43311
|
/* Allocate the iterator */
|
43019
43312
|
rc = walIteratorInit(pWal, &pIter);
|
@@ -43035,7 +43328,6 @@ static int walCheckpoint(
|
|
43035
43328
|
*/
|
43036
43329
|
mxSafeFrame = pWal->hdr.mxFrame;
|
43037
43330
|
mxPage = pWal->hdr.nPage;
|
43038
|
-
pInfo = walCkptInfo(pWal);
|
43039
43331
|
for(i=1; i<WAL_NREADER; i++){
|
43040
43332
|
u32 y = pInfo->aReadMark[i];
|
43041
43333
|
if( mxSafeFrame>=y ){
|
@@ -44625,12 +44917,12 @@ struct BtShared {
|
|
44625
44917
|
u8 autoVacuum; /* True if auto-vacuum is enabled */
|
44626
44918
|
u8 incrVacuum; /* True if incr-vacuum is enabled */
|
44627
44919
|
#endif
|
44920
|
+
u8 inTransaction; /* Transaction state */
|
44921
|
+
u8 doNotUseWAL; /* If true, do not open write-ahead-log file */
|
44628
44922
|
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
|
44629
44923
|
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
|
44630
44924
|
u16 maxLeaf; /* Maximum local payload in a LEAFDATA table */
|
44631
44925
|
u16 minLeaf; /* Minimum local payload in a LEAFDATA table */
|
44632
|
-
u8 inTransaction; /* Transaction state */
|
44633
|
-
u8 doNotUseWAL; /* If true, do not open write-ahead-log file */
|
44634
44926
|
u32 pageSize; /* Total number of bytes on a page */
|
44635
44927
|
u32 usableSize; /* Number of usable bytes on each page */
|
44636
44928
|
int nTransaction; /* Number of open transactions (read + write) */
|
@@ -44657,8 +44949,8 @@ struct BtShared {
|
|
44657
44949
|
*/
|
44658
44950
|
typedef struct CellInfo CellInfo;
|
44659
44951
|
struct CellInfo {
|
44660
|
-
u8 *pCell; /* Pointer to the start of cell content */
|
44661
44952
|
i64 nKey; /* The key for INTKEY tables, or number of bytes in key */
|
44953
|
+
u8 *pCell; /* Pointer to the start of cell content */
|
44662
44954
|
u32 nData; /* Number of bytes of data */
|
44663
44955
|
u32 nPayload; /* Total amount of payload */
|
44664
44956
|
u16 nHeader; /* Size of the cell content header in bytes */
|
@@ -44700,20 +44992,20 @@ struct BtCursor {
|
|
44700
44992
|
Pgno pgnoRoot; /* The root page of this tree */
|
44701
44993
|
sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */
|
44702
44994
|
CellInfo info; /* A parse of the cell we are pointing at */
|
44995
|
+
i64 nKey; /* Size of pKey, or last integer key */
|
44996
|
+
void *pKey; /* Saved key that was cursor's last known position */
|
44997
|
+
int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
|
44703
44998
|
u8 wrFlag; /* True if writable */
|
44704
44999
|
u8 atLast; /* Cursor pointing to the last entry */
|
44705
45000
|
u8 validNKey; /* True if info.nKey is valid */
|
44706
45001
|
u8 eState; /* One of the CURSOR_XXX constants (see below) */
|
44707
|
-
void *pKey; /* Saved key that was cursor's last known position */
|
44708
|
-
i64 nKey; /* Size of pKey, or last integer key */
|
44709
|
-
int skipNext; /* Prev() is noop if negative. Next() is noop if positive */
|
44710
45002
|
#ifndef SQLITE_OMIT_INCRBLOB
|
44711
|
-
u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */
|
44712
45003
|
Pgno *aOverflow; /* Cache of overflow page locations */
|
45004
|
+
u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */
|
44713
45005
|
#endif
|
44714
45006
|
i16 iPage; /* Index of current page in apPage */
|
44715
|
-
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
44716
45007
|
u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */
|
45008
|
+
MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
|
44717
45009
|
};
|
44718
45010
|
|
44719
45011
|
/*
|
@@ -46117,14 +46409,9 @@ static void btreeParseCellPtr(
|
|
46117
46409
|
/* This is the (easy) common case where the entire payload fits
|
46118
46410
|
** on the local page. No overflow is required.
|
46119
46411
|
*/
|
46120
|
-
|
46121
|
-
nSize = nPayload + n;
|
46412
|
+
if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4;
|
46122
46413
|
pInfo->nLocal = (u16)nPayload;
|
46123
46414
|
pInfo->iOverflow = 0;
|
46124
|
-
if( (nSize & ~3)==0 ){
|
46125
|
-
nSize = 4; /* Minimum cell size is 4 */
|
46126
|
-
}
|
46127
|
-
pInfo->nSize = (u16)nSize;
|
46128
46415
|
}else{
|
46129
46416
|
/* If the payload will not fit completely on the local page, we have
|
46130
46417
|
** to decide how much to store locally and how much to spill onto
|
@@ -47585,7 +47872,7 @@ static int lockBtree(BtShared *pBt){
|
|
47585
47872
|
pageSize-usableSize);
|
47586
47873
|
return rc;
|
47587
47874
|
}
|
47588
|
-
if( nPageHeader>nPageFile ){
|
47875
|
+
if( (pBt->db->flags & SQLITE_RecoveryMode)==0 && nPageHeader>nPageFile ){
|
47589
47876
|
rc = SQLITE_CORRUPT_BKPT;
|
47590
47877
|
goto page1_init_failed;
|
47591
47878
|
}
|
@@ -53457,6 +53744,16 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
|
|
53457
53744
|
return pDb->aDb[i].pBt;
|
53458
53745
|
}
|
53459
53746
|
|
53747
|
+
/*
|
53748
|
+
** Attempt to set the page size of the destination to match the page size
|
53749
|
+
** of the source.
|
53750
|
+
*/
|
53751
|
+
static int setDestPgsz(sqlite3_backup *p){
|
53752
|
+
int rc;
|
53753
|
+
rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
|
53754
|
+
return rc;
|
53755
|
+
}
|
53756
|
+
|
53460
53757
|
/*
|
53461
53758
|
** Create an sqlite3_backup process to copy the contents of zSrcDb from
|
53462
53759
|
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
|
@@ -53510,10 +53807,11 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
|
|
53510
53807
|
p->iNext = 1;
|
53511
53808
|
p->isAttached = 0;
|
53512
53809
|
|
53513
|
-
if( 0==p->pSrc || 0==p->pDest ){
|
53514
|
-
/* One (or both) of the named databases did not exist
|
53515
|
-
** already been written into the
|
53516
|
-
** to do here is free the
|
53810
|
+
if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){
|
53811
|
+
/* One (or both) of the named databases did not exist or an OOM
|
53812
|
+
** error was hit. The error has already been written into the
|
53813
|
+
** pDestDb handle. All that is left to do here is free the
|
53814
|
+
** sqlite3_backup structure.
|
53517
53815
|
*/
|
53518
53816
|
sqlite3_free(p);
|
53519
53817
|
p = 0;
|
@@ -53770,32 +54068,46 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
|
|
53770
54068
|
*/
|
53771
54069
|
const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
|
53772
54070
|
sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
|
54071
|
+
i64 iOff;
|
54072
|
+
i64 iEnd;
|
53773
54073
|
|
53774
54074
|
assert( pFile );
|
53775
54075
|
assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
|
53776
54076
|
nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
|
53777
54077
|
&& iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
|
53778
54078
|
));
|
53779
|
-
|
53780
|
-
|
53781
|
-
|
54079
|
+
|
54080
|
+
/* This call ensures that all data required to recreate the original
|
54081
|
+
** database has been stored in the journal for pDestPager and the
|
54082
|
+
** journal synced to disk. So at this point we may safely modify
|
54083
|
+
** the database file in any way, knowing that if a power failure
|
54084
|
+
** occurs, the original database will be reconstructed from the
|
54085
|
+
** journal file. */
|
54086
|
+
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1);
|
54087
|
+
|
54088
|
+
/* Write the extra pages and truncate the database file as required. */
|
54089
|
+
iEnd = MIN(PENDING_BYTE + pgszDest, iSize);
|
54090
|
+
for(
|
54091
|
+
iOff=PENDING_BYTE+pgszSrc;
|
54092
|
+
rc==SQLITE_OK && iOff<iEnd;
|
54093
|
+
iOff+=pgszSrc
|
53782
54094
|
){
|
53783
|
-
|
53784
|
-
|
53785
|
-
|
53786
|
-
|
53787
|
-
|
53788
|
-
iOff
|
53789
|
-
){
|
53790
|
-
PgHdr *pSrcPg = 0;
|
53791
|
-
const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
|
53792
|
-
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
|
53793
|
-
if( rc==SQLITE_OK ){
|
53794
|
-
u8 *zData = sqlite3PagerGetData(pSrcPg);
|
53795
|
-
rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
|
53796
|
-
}
|
53797
|
-
sqlite3PagerUnref(pSrcPg);
|
54095
|
+
PgHdr *pSrcPg = 0;
|
54096
|
+
const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
|
54097
|
+
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg);
|
54098
|
+
if( rc==SQLITE_OK ){
|
54099
|
+
u8 *zData = sqlite3PagerGetData(pSrcPg);
|
54100
|
+
rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
|
53798
54101
|
}
|
54102
|
+
sqlite3PagerUnref(pSrcPg);
|
54103
|
+
}
|
54104
|
+
if( rc==SQLITE_OK ){
|
54105
|
+
rc = backupTruncateFile(pFile, iSize);
|
54106
|
+
}
|
54107
|
+
|
54108
|
+
/* Sync the database file to disk. */
|
54109
|
+
if( rc==SQLITE_OK ){
|
54110
|
+
rc = sqlite3PagerSync(pDestPager);
|
53799
54111
|
}
|
53800
54112
|
}else{
|
53801
54113
|
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
|
@@ -55558,7 +55870,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
|
55558
55870
|
pOp->opflags = sqlite3OpcodeProperty[opcode];
|
55559
55871
|
if( opcode==OP_Function || opcode==OP_AggStep ){
|
55560
55872
|
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
|
55561
|
-
}else if( opcode==OP_Transaction && pOp->p2!=0 ){
|
55873
|
+
}else if( (opcode==OP_Transaction && pOp->p2!=0) || opcode==OP_Vacuum ){
|
55562
55874
|
p->readOnly = 0;
|
55563
55875
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
55564
55876
|
}else if( opcode==OP_VUpdate ){
|
@@ -58655,11 +58967,30 @@ static int sqlite3Step(Vdbe *p){
|
|
58655
58967
|
assert(p);
|
58656
58968
|
if( p->magic!=VDBE_MAGIC_RUN ){
|
58657
58969
|
/* We used to require that sqlite3_reset() be called before retrying
|
58658
|
-
** sqlite3_step() after any error
|
58659
|
-
** so that sqlite3_reset() would
|
58660
|
-
** throwing the error.
|
58970
|
+
** sqlite3_step() after any error or after SQLITE_DONE. But beginning
|
58971
|
+
** with version 3.7.0, we changed this so that sqlite3_reset() would
|
58972
|
+
** be called automatically instead of throwing the SQLITE_MISUSE error.
|
58973
|
+
** This "automatic-reset" change is not technically an incompatibility,
|
58974
|
+
** since any application that receives an SQLITE_MISUSE is broken by
|
58975
|
+
** definition.
|
58976
|
+
**
|
58977
|
+
** Nevertheless, some published applications that were originally written
|
58978
|
+
** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
|
58979
|
+
** returns, and the so were broken by the automatic-reset change. As a
|
58980
|
+
** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
|
58981
|
+
** legacy behavior of returning SQLITE_MISUSE for cases where the
|
58982
|
+
** previous sqlite3_step() returned something other than a SQLITE_LOCKED
|
58983
|
+
** or SQLITE_BUSY error.
|
58661
58984
|
*/
|
58985
|
+
#ifdef SQLITE_OMIT_AUTORESET
|
58986
|
+
if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
|
58987
|
+
sqlite3_reset((sqlite3_stmt*)p);
|
58988
|
+
}else{
|
58989
|
+
return SQLITE_MISUSE_BKPT;
|
58990
|
+
}
|
58991
|
+
#else
|
58662
58992
|
sqlite3_reset((sqlite3_stmt*)p);
|
58993
|
+
#endif
|
58663
58994
|
}
|
58664
58995
|
|
58665
58996
|
/* Check that malloc() has not failed. If it has, return early. */
|
@@ -58701,7 +59032,9 @@ static int sqlite3Step(Vdbe *p){
|
|
58701
59032
|
}else
|
58702
59033
|
#endif /* SQLITE_OMIT_EXPLAIN */
|
58703
59034
|
{
|
59035
|
+
db->vdbeExecCnt++;
|
58704
59036
|
rc = sqlite3VdbeExec(p);
|
59037
|
+
db->vdbeExecCnt--;
|
58705
59038
|
}
|
58706
59039
|
|
58707
59040
|
#ifndef SQLITE_OMIT_TRACE
|
@@ -58995,7 +59328,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
|
|
58995
59328
|
#if defined(SQLITE_DEBUG) && defined(__GNUC__)
|
58996
59329
|
__attribute__((aligned(8)))
|
58997
59330
|
#endif
|
58998
|
-
= {
|
59331
|
+
= {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
|
58999
59332
|
|
59000
59333
|
if( pVm && ALWAYS(pVm->db) ){
|
59001
59334
|
sqlite3_mutex_enter(pVm->db->mutex);
|
@@ -59658,9 +59991,12 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
|
|
59658
59991
|
}
|
59659
59992
|
|
59660
59993
|
/*
|
59661
|
-
**
|
59662
|
-
**
|
59663
|
-
**
|
59994
|
+
** This function returns a pointer to a nul-terminated string in memory
|
59995
|
+
** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
|
59996
|
+
** string contains a copy of zRawSql but with host parameters expanded to
|
59997
|
+
** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1,
|
59998
|
+
** then the returned string holds a copy of zRawSql with "-- " prepended
|
59999
|
+
** to each line of text.
|
59664
60000
|
**
|
59665
60001
|
** The calling function is responsible for making sure the memory returned
|
59666
60002
|
** is eventually freed.
|
@@ -59691,63 +60027,72 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
|
|
59691
60027
|
sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
|
59692
60028
|
db->aLimit[SQLITE_LIMIT_LENGTH]);
|
59693
60029
|
out.db = db;
|
59694
|
-
|
59695
|
-
|
59696
|
-
|
59697
|
-
|
59698
|
-
|
59699
|
-
|
59700
|
-
|
59701
|
-
|
59702
|
-
|
59703
|
-
|
59704
|
-
|
60030
|
+
if( db->vdbeExecCnt>1 ){
|
60031
|
+
while( *zRawSql ){
|
60032
|
+
const char *zStart = zRawSql;
|
60033
|
+
while( *(zRawSql++)!='\n' && *zRawSql );
|
60034
|
+
sqlite3StrAccumAppend(&out, "-- ", 3);
|
60035
|
+
sqlite3StrAccumAppend(&out, zStart, zRawSql-zStart);
|
60036
|
+
}
|
60037
|
+
}else{
|
60038
|
+
while( zRawSql[0] ){
|
60039
|
+
n = findNextHostParameter(zRawSql, &nToken);
|
60040
|
+
assert( n>0 );
|
60041
|
+
sqlite3StrAccumAppend(&out, zRawSql, n);
|
60042
|
+
zRawSql += n;
|
60043
|
+
assert( zRawSql[0] || nToken==0 );
|
60044
|
+
if( nToken==0 ) break;
|
60045
|
+
if( zRawSql[0]=='?' ){
|
60046
|
+
if( nToken>1 ){
|
60047
|
+
assert( sqlite3Isdigit(zRawSql[1]) );
|
60048
|
+
sqlite3GetInt32(&zRawSql[1], &idx);
|
60049
|
+
}else{
|
60050
|
+
idx = nextIndex;
|
60051
|
+
}
|
59705
60052
|
}else{
|
59706
|
-
|
59707
|
-
|
59708
|
-
|
59709
|
-
|
59710
|
-
|
59711
|
-
|
59712
|
-
|
59713
|
-
|
59714
|
-
|
59715
|
-
|
59716
|
-
|
59717
|
-
|
59718
|
-
|
59719
|
-
|
59720
|
-
|
59721
|
-
|
59722
|
-
|
59723
|
-
|
59724
|
-
}else if( pVar->flags & MEM_Real ){
|
59725
|
-
sqlite3XPrintf(&out, "%!.15g", pVar->r);
|
59726
|
-
}else if( pVar->flags & MEM_Str ){
|
60053
|
+
assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
|
60054
|
+
testcase( zRawSql[0]==':' );
|
60055
|
+
testcase( zRawSql[0]=='$' );
|
60056
|
+
testcase( zRawSql[0]=='@' );
|
60057
|
+
idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
|
60058
|
+
assert( idx>0 );
|
60059
|
+
}
|
60060
|
+
zRawSql += nToken;
|
60061
|
+
nextIndex = idx + 1;
|
60062
|
+
assert( idx>0 && idx<=p->nVar );
|
60063
|
+
pVar = &p->aVar[idx-1];
|
60064
|
+
if( pVar->flags & MEM_Null ){
|
60065
|
+
sqlite3StrAccumAppend(&out, "NULL", 4);
|
60066
|
+
}else if( pVar->flags & MEM_Int ){
|
60067
|
+
sqlite3XPrintf(&out, "%lld", pVar->u.i);
|
60068
|
+
}else if( pVar->flags & MEM_Real ){
|
60069
|
+
sqlite3XPrintf(&out, "%!.15g", pVar->r);
|
60070
|
+
}else if( pVar->flags & MEM_Str ){
|
59727
60071
|
#ifndef SQLITE_OMIT_UTF16
|
59728
|
-
|
59729
|
-
|
59730
|
-
|
59731
|
-
|
59732
|
-
|
59733
|
-
|
59734
|
-
|
59735
|
-
|
59736
|
-
|
59737
|
-
|
60072
|
+
u8 enc = ENC(db);
|
60073
|
+
if( enc!=SQLITE_UTF8 ){
|
60074
|
+
Mem utf8;
|
60075
|
+
memset(&utf8, 0, sizeof(utf8));
|
60076
|
+
utf8.db = db;
|
60077
|
+
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
|
60078
|
+
sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
|
60079
|
+
sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
|
60080
|
+
sqlite3VdbeMemRelease(&utf8);
|
60081
|
+
}else
|
59738
60082
|
#endif
|
59739
|
-
|
59740
|
-
|
59741
|
-
|
59742
|
-
|
59743
|
-
|
59744
|
-
|
59745
|
-
|
59746
|
-
|
59747
|
-
|
59748
|
-
|
60083
|
+
{
|
60084
|
+
sqlite3XPrintf(&out, "'%.*q'", pVar->n, pVar->z);
|
60085
|
+
}
|
60086
|
+
}else if( pVar->flags & MEM_Zero ){
|
60087
|
+
sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
|
60088
|
+
}else{
|
60089
|
+
assert( pVar->flags & MEM_Blob );
|
60090
|
+
sqlite3StrAccumAppend(&out, "x'", 2);
|
60091
|
+
for(i=0; i<pVar->n; i++){
|
60092
|
+
sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
|
60093
|
+
}
|
60094
|
+
sqlite3StrAccumAppend(&out, "'", 1);
|
59749
60095
|
}
|
59750
|
-
sqlite3StrAccumAppend(&out, "'", 1);
|
59751
60096
|
}
|
59752
60097
|
}
|
59753
60098
|
return sqlite3StrAccumFinish(&out);
|
@@ -73442,9 +73787,10 @@ static void analyzeOneTable(
|
|
73442
73787
|
sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);
|
73443
73788
|
|
73444
73789
|
for(i=0; i<nCol; i++){
|
73790
|
+
CollSeq *pColl;
|
73445
73791
|
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
|
73446
|
-
#ifdef SQLITE_ENABLE_STAT2
|
73447
73792
|
if( i==0 ){
|
73793
|
+
#ifdef SQLITE_ENABLE_STAT2
|
73448
73794
|
/* Check if the record that cursor iIdxCur points to contains a
|
73449
73795
|
** value that should be stored in the sqlite_stat2 table. If so,
|
73450
73796
|
** store it. */
|
@@ -73473,12 +73819,17 @@ static void analyzeOneTable(
|
|
73473
73819
|
|
73474
73820
|
sqlite3VdbeJumpHere(v, ne);
|
73475
73821
|
sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
|
73476
|
-
}
|
73477
73822
|
#endif
|
73478
73823
|
|
73479
|
-
|
73480
|
-
|
73481
|
-
|
73824
|
+
/* Always record the very first row */
|
73825
|
+
sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
|
73826
|
+
}
|
73827
|
+
assert( pIdx->azColl!=0 );
|
73828
|
+
assert( pIdx->azColl[i]!=0 );
|
73829
|
+
pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
|
73830
|
+
sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
|
73831
|
+
(char*)pColl, P4_COLLSEQ);
|
73832
|
+
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
73482
73833
|
}
|
73483
73834
|
if( db->mallocFailed ){
|
73484
73835
|
/* If a malloc failure has occurred, then the result of the expression
|
@@ -73489,7 +73840,11 @@ static void analyzeOneTable(
|
|
73489
73840
|
}
|
73490
73841
|
sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
|
73491
73842
|
for(i=0; i<nCol; i++){
|
73492
|
-
|
73843
|
+
int addr2 = sqlite3VdbeCurrentAddr(v) - (nCol*2);
|
73844
|
+
if( i==0 ){
|
73845
|
+
sqlite3VdbeJumpHere(v, addr2-1); /* Set jump dest for the OP_IfNot */
|
73846
|
+
}
|
73847
|
+
sqlite3VdbeJumpHere(v, addr2); /* Set jump dest for the OP_Ne */
|
73493
73848
|
sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
|
73494
73849
|
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
|
73495
73850
|
}
|
@@ -73835,8 +74190,11 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
|
73835
74190
|
|
73836
74191
|
if( rc==SQLITE_OK ){
|
73837
74192
|
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
73838
|
-
char *zIndex
|
73839
|
-
Index *pIdx
|
74193
|
+
char *zIndex; /* Index name */
|
74194
|
+
Index *pIdx; /* Pointer to the index object */
|
74195
|
+
|
74196
|
+
zIndex = (char *)sqlite3_column_text(pStmt, 0);
|
74197
|
+
pIdx = zIndex ? sqlite3FindIndex(db, zIndex, sInfo.zDatabase) : 0;
|
73840
74198
|
if( pIdx ){
|
73841
74199
|
int iSample = sqlite3_column_int(pStmt, 1);
|
73842
74200
|
if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){
|
@@ -80923,9 +81281,9 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
|
|
80923
81281
|
}else{
|
80924
81282
|
pInfo = (struct compareInfo*)&likeInfoNorm;
|
80925
81283
|
}
|
80926
|
-
sqlite3CreateFunc(db, "like", 2,
|
80927
|
-
sqlite3CreateFunc(db, "like", 3,
|
80928
|
-
sqlite3CreateFunc(db, "glob", 2,
|
81284
|
+
sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
|
81285
|
+
sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0);
|
81286
|
+
sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8,
|
80929
81287
|
(struct compareInfo*)&globInfo, likeFunc, 0, 0, 0);
|
80930
81288
|
setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
|
80931
81289
|
setLikeOptFlag(db, "like",
|
@@ -87604,7 +87962,7 @@ SQLITE_API int sqlite3_prepare_v2(
|
|
87604
87962
|
*/
|
87605
87963
|
static int sqlite3Prepare16(
|
87606
87964
|
sqlite3 *db, /* Database handle. */
|
87607
|
-
const void *zSql, /* UTF-
|
87965
|
+
const void *zSql, /* UTF-16 encoded SQL statement. */
|
87608
87966
|
int nBytes, /* Length of zSql in bytes. */
|
87609
87967
|
int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */
|
87610
87968
|
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
|
@@ -87654,7 +88012,7 @@ static int sqlite3Prepare16(
|
|
87654
88012
|
*/
|
87655
88013
|
SQLITE_API int sqlite3_prepare16(
|
87656
88014
|
sqlite3 *db, /* Database handle. */
|
87657
|
-
const void *zSql, /* UTF-
|
88015
|
+
const void *zSql, /* UTF-16 encoded SQL statement. */
|
87658
88016
|
int nBytes, /* Length of zSql in bytes. */
|
87659
88017
|
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
|
87660
88018
|
const void **pzTail /* OUT: End of parsed string */
|
@@ -87666,7 +88024,7 @@ SQLITE_API int sqlite3_prepare16(
|
|
87666
88024
|
}
|
87667
88025
|
SQLITE_API int sqlite3_prepare16_v2(
|
87668
88026
|
sqlite3 *db, /* Database handle. */
|
87669
|
-
const void *zSql, /* UTF-
|
88027
|
+
const void *zSql, /* UTF-16 encoded SQL statement. */
|
87670
88028
|
int nBytes, /* Length of zSql in bytes. */
|
87671
88029
|
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
|
87672
88030
|
const void **pzTail /* OUT: End of parsed string */
|
@@ -97675,10 +98033,9 @@ static int valueFromExpr(
|
|
97675
98033
|
u8 aff,
|
97676
98034
|
sqlite3_value **pp
|
97677
98035
|
){
|
97678
|
-
|
97679
|
-
|
97680
|
-
|
97681
|
-
if( pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE ){
|
98036
|
+
if( pExpr->op==TK_VARIABLE
|
98037
|
+
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
|
98038
|
+
){
|
97682
98039
|
int iVar = pExpr->iColumn;
|
97683
98040
|
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-23257-02778 */
|
97684
98041
|
*pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
|
@@ -105466,7 +105823,7 @@ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){
|
|
105466
105823
|
/* SQLITE_INTERRUPT */ "interrupted",
|
105467
105824
|
/* SQLITE_IOERR */ "disk I/O error",
|
105468
105825
|
/* SQLITE_CORRUPT */ "database disk image is malformed",
|
105469
|
-
/* SQLITE_NOTFOUND */
|
105826
|
+
/* SQLITE_NOTFOUND */ "unknown operation",
|
105470
105827
|
/* SQLITE_FULL */ "database or disk is full",
|
105471
105828
|
/* SQLITE_CANTOPEN */ "unable to open database file",
|
105472
105829
|
/* SQLITE_PROTOCOL */ "locking protocol",
|
@@ -106471,6 +106828,9 @@ static int openDatabase(
|
|
106471
106828
|
#endif
|
106472
106829
|
#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
|
106473
106830
|
| SQLITE_RecTriggers
|
106831
|
+
#endif
|
106832
|
+
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
|
106833
|
+
| SQLITE_ForeignKeys
|
106474
106834
|
#endif
|
106475
106835
|
;
|
106476
106836
|
sqlite3HashInit(&db->aCollSeq);
|
@@ -107011,6 +107371,8 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo
|
|
107011
107371
|
rc = SQLITE_OK;
|
107012
107372
|
}else if( fd->pMethods ){
|
107013
107373
|
rc = sqlite3OsFileControl(fd, op, pArg);
|
107374
|
+
}else{
|
107375
|
+
rc = SQLITE_NOTFOUND;
|
107014
107376
|
}
|
107015
107377
|
sqlite3BtreeLeave(pBtree);
|
107016
107378
|
}
|
@@ -111309,9 +111671,16 @@ SQLITE_PRIVATE char *sqlite3Fts3FindPositions(
|
|
111309
111671
|
assert( pExpr->isLoaded );
|
111310
111672
|
if( pExpr->aDoclist ){
|
111311
111673
|
char *pEnd = &pExpr->aDoclist[pExpr->nDoclist];
|
111312
|
-
char *pCsr
|
111674
|
+
char *pCsr;
|
111313
111675
|
|
111676
|
+
if( pExpr->pCurrent==0 ){
|
111677
|
+
pExpr->pCurrent = pExpr->aDoclist;
|
111678
|
+
pExpr->iCurrent = 0;
|
111679
|
+
pExpr->pCurrent += sqlite3Fts3GetVarint(pExpr->pCurrent,&pExpr->iCurrent);
|
111680
|
+
}
|
111681
|
+
pCsr = pExpr->pCurrent;
|
111314
111682
|
assert( pCsr );
|
111683
|
+
|
111315
111684
|
while( pCsr<pEnd ){
|
111316
111685
|
if( pExpr->iCurrent<iDocid ){
|
111317
111686
|
fts3PoslistCopy(0, &pCsr);
|
@@ -115500,24 +115869,28 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderCost(
|
|
115500
115869
|
** to right.
|
115501
115870
|
*/
|
115502
115871
|
sqlite3_stmt *pStmt;
|
115503
|
-
|
115872
|
+
sqlite3_int64 nDoc = 0;
|
115873
|
+
sqlite3_int64 nByte = 0;
|
115874
|
+
const char *a;
|
115875
|
+
rc = sqlite3Fts3SelectDoctotal(p, &pStmt);
|
115504
115876
|
if( rc ) return rc;
|
115505
|
-
|
115506
|
-
|
115507
|
-
|
115508
|
-
|
115509
|
-
|
115510
|
-
|
115511
|
-
a += sqlite3Fts3GetVarint(a, &nDoc);
|
115512
|
-
while( a<pEnd ){
|
115513
|
-
a += sqlite3Fts3GetVarint(a, &nByte);
|
115514
|
-
}
|
115877
|
+
a = sqlite3_column_blob(pStmt, 0);
|
115878
|
+
if( a ){
|
115879
|
+
const char *pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
|
115880
|
+
a += sqlite3Fts3GetVarint(a, &nDoc);
|
115881
|
+
while( a<pEnd ){
|
115882
|
+
a += sqlite3Fts3GetVarint(a, &nByte);
|
115515
115883
|
}
|
115516
|
-
|
115517
|
-
pCsr->nRowAvg = (int)(((nByte / nDoc) + pgsz - 1) / pgsz);
|
115518
115884
|
}
|
115885
|
+
if( nDoc==0 || nByte==0 ){
|
115886
|
+
sqlite3_reset(pStmt);
|
115887
|
+
return SQLITE_CORRUPT;
|
115888
|
+
}
|
115889
|
+
|
115890
|
+
pCsr->nRowAvg = (int)(((nByte / nDoc) + pgsz) / pgsz);
|
115891
|
+
assert( pCsr->nRowAvg>0 );
|
115519
115892
|
rc = sqlite3_reset(pStmt);
|
115520
|
-
if( rc!=SQLITE_OK
|
115893
|
+
if( rc!=SQLITE_OK ) return rc;
|
115521
115894
|
}
|
115522
115895
|
|
115523
115896
|
/* Assume that a blob flows over onto overflow pages if it is larger
|
@@ -116638,7 +117011,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderIterate(
|
|
116638
117011
|
nByte = sqlite3Fts3VarintLen(iDocid-iPrev) + (isRequirePos?nList+1:0);
|
116639
117012
|
if( nDoclist+nByte>nAlloc ){
|
116640
117013
|
char *aNew;
|
116641
|
-
nAlloc = nDoclist+nByte*2;
|
117014
|
+
nAlloc = (nDoclist+nByte)*2;
|
116642
117015
|
aNew = sqlite3_realloc(aBuffer, nAlloc);
|
116643
117016
|
if( !aNew ){
|
116644
117017
|
rc = SQLITE_NOMEM;
|
@@ -117515,7 +117888,7 @@ static int fts3ExprNearTrim(Fts3Expr *pExpr){
|
|
117515
117888
|
** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
|
117516
117889
|
** fts3ExprLoadDoclists().
|
117517
117890
|
*/
|
117518
|
-
static int
|
117891
|
+
static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
117519
117892
|
int rc = SQLITE_OK;
|
117520
117893
|
LoadDoclistCtx *p = (LoadDoclistCtx *)ctx;
|
117521
117894
|
|
@@ -117535,22 +117908,6 @@ static int fts3ExprLoadDoclistsCb1(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
|
117535
117908
|
return rc;
|
117536
117909
|
}
|
117537
117910
|
|
117538
|
-
/*
|
117539
|
-
** This is an fts3ExprIterate() callback used while loading the doclists
|
117540
|
-
** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
|
117541
|
-
** fts3ExprLoadDoclists().
|
117542
|
-
*/
|
117543
|
-
static int fts3ExprLoadDoclistsCb2(Fts3Expr *pExpr, int iPhrase, void *ctx){
|
117544
|
-
UNUSED_PARAMETER(iPhrase);
|
117545
|
-
UNUSED_PARAMETER(ctx);
|
117546
|
-
if( pExpr->aDoclist ){
|
117547
|
-
pExpr->pCurrent = pExpr->aDoclist;
|
117548
|
-
pExpr->iCurrent = 0;
|
117549
|
-
pExpr->pCurrent += sqlite3Fts3GetVarint(pExpr->pCurrent, &pExpr->iCurrent);
|
117550
|
-
}
|
117551
|
-
return SQLITE_OK;
|
117552
|
-
}
|
117553
|
-
|
117554
117911
|
/*
|
117555
117912
|
** Load the doclists for each phrase in the query associated with FTS3 cursor
|
117556
117913
|
** pCsr.
|
@@ -117569,10 +117926,7 @@ static int fts3ExprLoadDoclists(
|
|
117569
117926
|
int rc; /* Return Code */
|
117570
117927
|
LoadDoclistCtx sCtx = {0,0,0}; /* Context for fts3ExprIterate() */
|
117571
117928
|
sCtx.pCsr = pCsr;
|
117572
|
-
rc = fts3ExprIterate(pCsr->pExpr,
|
117573
|
-
if( rc==SQLITE_OK ){
|
117574
|
-
(void)fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb2, 0);
|
117575
|
-
}
|
117929
|
+
rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx);
|
117576
117930
|
if( pnPhrase ) *pnPhrase = sCtx.nPhrase;
|
117577
117931
|
if( pnToken ) *pnToken = sCtx.nToken;
|
117578
117932
|
return rc;
|
@@ -118264,6 +118618,7 @@ static int fts3MatchinfoSelectDoctotal(
|
|
118264
118618
|
if( rc!=SQLITE_OK ) return rc;
|
118265
118619
|
}
|
118266
118620
|
pStmt = *ppStmt;
|
118621
|
+
assert( sqlite3_data_count(pStmt)==1 );
|
118267
118622
|
|
118268
118623
|
a = sqlite3_column_blob(pStmt, 0);
|
118269
118624
|
a += sqlite3Fts3GetVarint(a, &nDoc);
|