Fossil SCM

Update the built-in SQLite to the latest 3.47.0 alpha, for testing.

drh 2024-09-18 11:53 trunk
Commit 5522ad5fa42bf05f1c2a467ceb35a4a0cb8e9bbd9408872c5e0fa302939b5598
3 files changed +1420 -18 +524 -364 +1 -1
+1420 -18
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1212,10 +1212,14 @@
12121212
++rv;
12131213
}
12141214
return rv;
12151215
}
12161216
1217
+/* An fgets() equivalent, using Win32 file API for actual input.
1218
+** Input ends when given buffer is filled or a newline is read.
1219
+** If the FILE object is in text mode, swallows 0x0D. (ASCII CR)
1220
+*/
12171221
SQLITE_INTERNAL_LINKAGE char *
12181222
cfGets(char *cBuf, int n, FILE *pf){
12191223
int nci = 0;
12201224
struct FileAltIds fai = altIdsOfFile(pf);
12211225
int fmode = _setmode(fai.fd, _O_BINARY);
@@ -1222,11 +1226,14 @@
12221226
BOOL eatCR = (fmode & _O_TEXT)!=0;
12231227
_setmode(fai.fd, fmode);
12241228
while( nci < n-1 ){
12251229
DWORD nr;
12261230
if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
1227
- if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
1231
+ if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){
1232
+ nci += nr;
1233
+ if( cBuf[nci-nr]=='\n' ) break;
1234
+ }
12281235
}
12291236
if( nci < n ) cBuf[nci] = 0;
12301237
return (nci>0)? cBuf : 0;
12311238
}
12321239
# else
@@ -3783,10 +3790,422 @@
37833790
}
37843791
return rc;
37853792
}
37863793
37873794
/************************* End ../ext/misc/shathree.c ********************/
3795
+/************************* Begin ../ext/misc/sha1.c ******************/
3796
+/*
3797
+** 2017-01-27
3798
+**
3799
+** The author disclaims copyright to this source code. In place of
3800
+** a legal notice, here is a blessing:
3801
+**
3802
+** May you do good and not evil.
3803
+** May you find forgiveness for yourself and forgive others.
3804
+** May you share freely, never taking more than you give.
3805
+**
3806
+******************************************************************************
3807
+**
3808
+** This SQLite extension implements functions that compute SHA1 hashes.
3809
+** Two SQL functions are implemented:
3810
+**
3811
+** sha1(X)
3812
+** sha1_query(Y)
3813
+**
3814
+** The sha1(X) function computes the SHA1 hash of the input X, or NULL if
3815
+** X is NULL.
3816
+**
3817
+** The sha1_query(Y) function evalutes all queries in the SQL statements of Y
3818
+** and returns a hash of their results.
3819
+*/
3820
+/* #include "sqlite3ext.h" */
3821
+SQLITE_EXTENSION_INIT1
3822
+#include <assert.h>
3823
+#include <string.h>
3824
+#include <stdarg.h>
3825
+
3826
+/******************************************************************************
3827
+** The Hash Engine
3828
+*/
3829
+/* Context for the SHA1 hash */
3830
+typedef struct SHA1Context SHA1Context;
3831
+struct SHA1Context {
3832
+ unsigned int state[5];
3833
+ unsigned int count[2];
3834
+ unsigned char buffer[64];
3835
+};
3836
+
3837
+#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
3838
+#define rol(x,k) SHA_ROT(x,k,32-(k))
3839
+#define ror(x,k) SHA_ROT(x,32-(k),k)
3840
+
3841
+#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
3842
+ |(rol(block[i],8)&0x00FF00FF))
3843
+#define blk0be(i) block[i]
3844
+#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
3845
+ ^block[(i+2)&15]^block[i&15],1))
3846
+
3847
+/*
3848
+ * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
3849
+ *
3850
+ * Rl0() for little-endian and Rb0() for big-endian. Endianness is
3851
+ * determined at run-time.
3852
+ */
3853
+#define Rl0(v,w,x,y,z,i) \
3854
+ z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2);
3855
+#define Rb0(v,w,x,y,z,i) \
3856
+ z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2);
3857
+#define R1(v,w,x,y,z,i) \
3858
+ z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2);
3859
+#define R2(v,w,x,y,z,i) \
3860
+ z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2);
3861
+#define R3(v,w,x,y,z,i) \
3862
+ z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2);
3863
+#define R4(v,w,x,y,z,i) \
3864
+ z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2);
3865
+
3866
+/*
3867
+ * Hash a single 512-bit block. This is the core of the algorithm.
3868
+ */
3869
+static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
3870
+ unsigned int qq[5]; /* a, b, c, d, e; */
3871
+ static int one = 1;
3872
+ unsigned int block[16];
3873
+ memcpy(block, buffer, 64);
3874
+ memcpy(qq,state,5*sizeof(unsigned int));
3875
+
3876
+#define a qq[0]
3877
+#define b qq[1]
3878
+#define c qq[2]
3879
+#define d qq[3]
3880
+#define e qq[4]
3881
+
3882
+ /* Copy p->state[] to working vars */
3883
+ /*
3884
+ a = state[0];
3885
+ b = state[1];
3886
+ c = state[2];
3887
+ d = state[3];
3888
+ e = state[4];
3889
+ */
3890
+
3891
+ /* 4 rounds of 20 operations each. Loop unrolled. */
3892
+ if( 1 == *(unsigned char*)&one ){
3893
+ Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3);
3894
+ Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7);
3895
+ Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11);
3896
+ Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15);
3897
+ }else{
3898
+ Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3);
3899
+ Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7);
3900
+ Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11);
3901
+ Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15);
3902
+ }
3903
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
3904
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
3905
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
3906
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
3907
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
3908
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
3909
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
3910
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
3911
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
3912
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
3913
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
3914
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
3915
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
3916
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
3917
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
3918
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
3919
+
3920
+ /* Add the working vars back into context.state[] */
3921
+ state[0] += a;
3922
+ state[1] += b;
3923
+ state[2] += c;
3924
+ state[3] += d;
3925
+ state[4] += e;
3926
+
3927
+#undef a
3928
+#undef b
3929
+#undef c
3930
+#undef d
3931
+#undef e
3932
+}
3933
+
3934
+
3935
+/* Initialize a SHA1 context */
3936
+static void hash_init(SHA1Context *p){
3937
+ /* SHA1 initialization constants */
3938
+ p->state[0] = 0x67452301;
3939
+ p->state[1] = 0xEFCDAB89;
3940
+ p->state[2] = 0x98BADCFE;
3941
+ p->state[3] = 0x10325476;
3942
+ p->state[4] = 0xC3D2E1F0;
3943
+ p->count[0] = p->count[1] = 0;
3944
+}
3945
+
3946
+/* Add new content to the SHA1 hash */
3947
+static void hash_step(
3948
+ SHA1Context *p, /* Add content to this context */
3949
+ const unsigned char *data, /* Data to be added */
3950
+ unsigned int len /* Number of bytes in data */
3951
+){
3952
+ unsigned int i, j;
3953
+
3954
+ j = p->count[0];
3955
+ if( (p->count[0] += len << 3) < j ){
3956
+ p->count[1] += (len>>29)+1;
3957
+ }
3958
+ j = (j >> 3) & 63;
3959
+ if( (j + len) > 63 ){
3960
+ (void)memcpy(&p->buffer[j], data, (i = 64-j));
3961
+ SHA1Transform(p->state, p->buffer);
3962
+ for(; i + 63 < len; i += 64){
3963
+ SHA1Transform(p->state, &data[i]);
3964
+ }
3965
+ j = 0;
3966
+ }else{
3967
+ i = 0;
3968
+ }
3969
+ (void)memcpy(&p->buffer[j], &data[i], len - i);
3970
+}
3971
+
3972
+/* Compute a string using sqlite3_vsnprintf() and hash it */
3973
+static void hash_step_vformat(
3974
+ SHA1Context *p, /* Add content to this context */
3975
+ const char *zFormat,
3976
+ ...
3977
+){
3978
+ va_list ap;
3979
+ int n;
3980
+ char zBuf[50];
3981
+ va_start(ap, zFormat);
3982
+ sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
3983
+ va_end(ap);
3984
+ n = (int)strlen(zBuf);
3985
+ hash_step(p, (unsigned char*)zBuf, n);
3986
+}
3987
+
3988
+
3989
+/* Add padding and compute the message digest. Render the
3990
+** message digest as lower-case hexadecimal and put it into
3991
+** zOut[]. zOut[] must be at least 41 bytes long. */
3992
+static void hash_finish(
3993
+ SHA1Context *p, /* The SHA1 context to finish and render */
3994
+ char *zOut, /* Store hex or binary hash here */
3995
+ int bAsBinary /* 1 for binary hash, 0 for hex hash */
3996
+){
3997
+ unsigned int i;
3998
+ unsigned char finalcount[8];
3999
+ unsigned char digest[20];
4000
+ static const char zEncode[] = "0123456789abcdef";
4001
+
4002
+ for (i = 0; i < 8; i++){
4003
+ finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)]
4004
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
4005
+ }
4006
+ hash_step(p, (const unsigned char *)"\200", 1);
4007
+ while ((p->count[0] & 504) != 448){
4008
+ hash_step(p, (const unsigned char *)"\0", 1);
4009
+ }
4010
+ hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */
4011
+ for (i = 0; i < 20; i++){
4012
+ digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
4013
+ }
4014
+ if( bAsBinary ){
4015
+ memcpy(zOut, digest, 20);
4016
+ }else{
4017
+ for(i=0; i<20; i++){
4018
+ zOut[i*2] = zEncode[(digest[i]>>4)&0xf];
4019
+ zOut[i*2+1] = zEncode[digest[i] & 0xf];
4020
+ }
4021
+ zOut[i*2]= 0;
4022
+ }
4023
+}
4024
+/* End of the hashing logic
4025
+*****************************************************************************/
4026
+
4027
+/*
4028
+** Implementation of the sha1(X) function.
4029
+**
4030
+** Return a lower-case hexadecimal rendering of the SHA1 hash of the
4031
+** argument X. If X is a BLOB, it is hashed as is. For all other
4032
+** types of input, X is converted into a UTF-8 string and the string
4033
+** is hash without the trailing 0x00 terminator. The hash of a NULL
4034
+** value is NULL.
4035
+*/
4036
+static void sha1Func(
4037
+ sqlite3_context *context,
4038
+ int argc,
4039
+ sqlite3_value **argv
4040
+){
4041
+ SHA1Context cx;
4042
+ int eType = sqlite3_value_type(argv[0]);
4043
+ int nByte = sqlite3_value_bytes(argv[0]);
4044
+ char zOut[44];
4045
+
4046
+ assert( argc==1 );
4047
+ if( eType==SQLITE_NULL ) return;
4048
+ hash_init(&cx);
4049
+ if( eType==SQLITE_BLOB ){
4050
+ hash_step(&cx, sqlite3_value_blob(argv[0]), nByte);
4051
+ }else{
4052
+ hash_step(&cx, sqlite3_value_text(argv[0]), nByte);
4053
+ }
4054
+ if( sqlite3_user_data(context)!=0 ){
4055
+ hash_finish(&cx, zOut, 1);
4056
+ sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
4057
+ }else{
4058
+ hash_finish(&cx, zOut, 0);
4059
+ sqlite3_result_blob(context, zOut, 40, SQLITE_TRANSIENT);
4060
+ }
4061
+}
4062
+
4063
+/*
4064
+** Implementation of the sha1_query(SQL) function.
4065
+**
4066
+** This function compiles and runs the SQL statement(s) given in the
4067
+** argument. The results are hashed using SHA1 and that hash is returned.
4068
+**
4069
+** The original SQL text is included as part of the hash.
4070
+**
4071
+** The hash is not just a concatenation of the outputs. Each query
4072
+** is delimited and each row and value within the query is delimited,
4073
+** with all values being marked with their datatypes.
4074
+*/
4075
+static void sha1QueryFunc(
4076
+ sqlite3_context *context,
4077
+ int argc,
4078
+ sqlite3_value **argv
4079
+){
4080
+ sqlite3 *db = sqlite3_context_db_handle(context);
4081
+ const char *zSql = (const char*)sqlite3_value_text(argv[0]);
4082
+ sqlite3_stmt *pStmt = 0;
4083
+ int nCol; /* Number of columns in the result set */
4084
+ int i; /* Loop counter */
4085
+ int rc;
4086
+ int n;
4087
+ const char *z;
4088
+ SHA1Context cx;
4089
+ char zOut[44];
4090
+
4091
+ assert( argc==1 );
4092
+ if( zSql==0 ) return;
4093
+ hash_init(&cx);
4094
+ while( zSql[0] ){
4095
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
4096
+ if( rc ){
4097
+ char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
4098
+ zSql, sqlite3_errmsg(db));
4099
+ sqlite3_finalize(pStmt);
4100
+ sqlite3_result_error(context, zMsg, -1);
4101
+ sqlite3_free(zMsg);
4102
+ return;
4103
+ }
4104
+ if( !sqlite3_stmt_readonly(pStmt) ){
4105
+ char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
4106
+ sqlite3_finalize(pStmt);
4107
+ sqlite3_result_error(context, zMsg, -1);
4108
+ sqlite3_free(zMsg);
4109
+ return;
4110
+ }
4111
+ nCol = sqlite3_column_count(pStmt);
4112
+ z = sqlite3_sql(pStmt);
4113
+ n = (int)strlen(z);
4114
+ hash_step_vformat(&cx,"S%d:",n);
4115
+ hash_step(&cx,(unsigned char*)z,n);
4116
+
4117
+ /* Compute a hash over the result of the query */
4118
+ while( SQLITE_ROW==sqlite3_step(pStmt) ){
4119
+ hash_step(&cx,(const unsigned char*)"R",1);
4120
+ for(i=0; i<nCol; i++){
4121
+ switch( sqlite3_column_type(pStmt,i) ){
4122
+ case SQLITE_NULL: {
4123
+ hash_step(&cx, (const unsigned char*)"N",1);
4124
+ break;
4125
+ }
4126
+ case SQLITE_INTEGER: {
4127
+ sqlite3_uint64 u;
4128
+ int j;
4129
+ unsigned char x[9];
4130
+ sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
4131
+ memcpy(&u, &v, 8);
4132
+ for(j=8; j>=1; j--){
4133
+ x[j] = u & 0xff;
4134
+ u >>= 8;
4135
+ }
4136
+ x[0] = 'I';
4137
+ hash_step(&cx, x, 9);
4138
+ break;
4139
+ }
4140
+ case SQLITE_FLOAT: {
4141
+ sqlite3_uint64 u;
4142
+ int j;
4143
+ unsigned char x[9];
4144
+ double r = sqlite3_column_double(pStmt,i);
4145
+ memcpy(&u, &r, 8);
4146
+ for(j=8; j>=1; j--){
4147
+ x[j] = u & 0xff;
4148
+ u >>= 8;
4149
+ }
4150
+ x[0] = 'F';
4151
+ hash_step(&cx,x,9);
4152
+ break;
4153
+ }
4154
+ case SQLITE_TEXT: {
4155
+ int n2 = sqlite3_column_bytes(pStmt, i);
4156
+ const unsigned char *z2 = sqlite3_column_text(pStmt, i);
4157
+ hash_step_vformat(&cx,"T%d:",n2);
4158
+ hash_step(&cx, z2, n2);
4159
+ break;
4160
+ }
4161
+ case SQLITE_BLOB: {
4162
+ int n2 = sqlite3_column_bytes(pStmt, i);
4163
+ const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
4164
+ hash_step_vformat(&cx,"B%d:",n2);
4165
+ hash_step(&cx, z2, n2);
4166
+ break;
4167
+ }
4168
+ }
4169
+ }
4170
+ }
4171
+ sqlite3_finalize(pStmt);
4172
+ }
4173
+ hash_finish(&cx, zOut, 0);
4174
+ sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
4175
+}
4176
+
4177
+
4178
+#ifdef _WIN32
4179
+
4180
+#endif
4181
+int sqlite3_sha_init(
4182
+ sqlite3 *db,
4183
+ char **pzErrMsg,
4184
+ const sqlite3_api_routines *pApi
4185
+){
4186
+ int rc = SQLITE_OK;
4187
+ static int one = 1;
4188
+ SQLITE_EXTENSION_INIT2(pApi);
4189
+ (void)pzErrMsg; /* Unused parameter */
4190
+ rc = sqlite3_create_function(db, "sha1", 1,
4191
+ SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
4192
+ 0, sha1Func, 0, 0);
4193
+ if( rc==SQLITE_OK ){
4194
+ rc = sqlite3_create_function(db, "sha1b", 1,
4195
+ SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
4196
+ (void*)&one, sha1Func, 0, 0);
4197
+ }
4198
+ if( rc==SQLITE_OK ){
4199
+ rc = sqlite3_create_function(db, "sha1_query", 1,
4200
+ SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
4201
+ sha1QueryFunc, 0, 0);
4202
+ }
4203
+ return rc;
4204
+}
4205
+
4206
+/************************* End ../ext/misc/sha1.c ********************/
37884207
/************************* Begin ../ext/misc/uint.c ******************/
37894208
/*
37904209
** 2020-04-14
37914210
**
37924211
** The author disclaims copyright to this source code. In place of
@@ -5075,11 +5494,11 @@
50755494
}else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
50765495
p->a[p->nUsed++] = y;
50775496
}else if( p->bKeepSorted ){
50785497
int i;
50795498
i = percentBinarySearch(p, y, 0);
5080
- if( i<p->nUsed ){
5499
+ if( i<(int)p->nUsed ){
50815500
memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
50825501
}
50835502
p->a[i] = y;
50845503
p->nUsed++;
50855504
}else{
@@ -5191,11 +5610,11 @@
51915610
51925611
/* Find and remove the row */
51935612
i = percentBinarySearch(p, y, 1);
51945613
if( i>=0 ){
51955614
p->nUsed--;
5196
- if( i<p->nUsed ){
5615
+ if( i<(int)p->nUsed ){
51975616
memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
51985617
}
51995618
}
52005619
}
52015620
@@ -5251,11 +5670,11 @@
52515670
sqlite3 *db,
52525671
char **pzErrMsg,
52535672
const sqlite3_api_routines *pApi
52545673
){
52555674
int rc = SQLITE_OK;
5256
- int i;
5675
+ unsigned int i;
52575676
#if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE)
52585677
(void)pApi; /* Unused parameter */
52595678
#else
52605679
SQLITE_EXTENSION_INIT2(pApi);
52615680
#endif
@@ -16211,10 +16630,1000 @@
1621116630
}
1621216631
return rc;
1621316632
}
1621416633
1621516634
/************************* End ../ext/misc/stmtrand.c ********************/
16635
+/************************* Begin ../ext/misc/vfstrace.c ******************/
16636
+/*
16637
+** 2011 March 16
16638
+**
16639
+** The author disclaims copyright to this source code. In place of
16640
+** a legal notice, here is a blessing:
16641
+**
16642
+** May you do good and not evil.
16643
+** May you find forgiveness for yourself and forgive others.
16644
+** May you share freely, never taking more than you give.
16645
+**
16646
+******************************************************************************
16647
+**
16648
+** This file contains code implements a VFS shim that writes diagnostic
16649
+** output for each VFS call, similar to "strace".
16650
+**
16651
+** USAGE:
16652
+**
16653
+** This source file exports a single symbol which is the name of a
16654
+** function:
16655
+**
16656
+** int vfstrace_register(
16657
+** const char *zTraceName, // Name of the newly constructed VFS
16658
+** const char *zOldVfsName, // Name of the underlying VFS
16659
+** int (*xOut)(const char*,void*), // Output routine. ex: fputs
16660
+** void *pOutArg, // 2nd argument to xOut. ex: stderr
16661
+** int makeDefault // Make the new VFS the default
16662
+** );
16663
+**
16664
+** Applications that want to trace their VFS usage must provide a callback
16665
+** function with this prototype:
16666
+**
16667
+** int traceOutput(const char *zMessage, void *pAppData);
16668
+**
16669
+** This function will "output" the trace messages, where "output" can
16670
+** mean different things to different applications. The traceOutput function
16671
+** for the command-line shell (see shell.c) is "fputs" from the standard
16672
+** library, which means that all trace output is written on the stream
16673
+** specified by the second argument. In the case of the command-line shell
16674
+** the second argument is stderr. Other applications might choose to output
16675
+** trace information to a file, over a socket, or write it into a buffer.
16676
+**
16677
+** The vfstrace_register() function creates a new "shim" VFS named by
16678
+** the zTraceName parameter. A "shim" VFS is an SQLite backend that does
16679
+** not really perform the duties of a true backend, but simply filters or
16680
+** interprets VFS calls before passing them off to another VFS which does
16681
+** the actual work. In this case the other VFS - the one that does the
16682
+** real work - is identified by the second parameter, zOldVfsName. If
16683
+** the 2nd parameter is NULL then the default VFS is used. The common
16684
+** case is for the 2nd parameter to be NULL.
16685
+**
16686
+** The third and fourth parameters are the pointer to the output function
16687
+** and the second argument to the output function. For the SQLite
16688
+** command-line shell, when the -vfstrace option is used, these parameters
16689
+** are fputs and stderr, respectively.
16690
+**
16691
+** The fifth argument is true (non-zero) to cause the newly created VFS
16692
+** to become the default VFS. The common case is for the fifth parameter
16693
+** to be true.
16694
+**
16695
+** The call to vfstrace_register() simply creates the shim VFS that does
16696
+** tracing. The application must also arrange to use the new VFS for
16697
+** all database connections that are created and for which tracing is
16698
+** desired. This can be done by specifying the trace VFS using URI filename
16699
+** notation, or by specifying the trace VFS as the 4th parameter to
16700
+** sqlite3_open_v2() or by making the trace VFS be the default (by setting
16701
+** the 5th parameter of vfstrace_register() to 1).
16702
+**
16703
+**
16704
+** ENABLING VFSTRACE IN A COMMAND-LINE SHELL
16705
+**
16706
+** The SQLite command line shell implemented by the shell.c source file
16707
+** can be used with this module. To compile in -vfstrace support, first
16708
+** gather this file (test_vfstrace.c), the shell source file (shell.c),
16709
+** and the SQLite amalgamation source files (sqlite3.c, sqlite3.h) into
16710
+** the working directory. Then compile using a command like the following:
16711
+**
16712
+** gcc -o sqlite3 -Os -I. -DSQLITE_ENABLE_VFSTRACE \
16713
+** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \
16714
+** -DHAVE_READLINE -DHAVE_USLEEP=1 \
16715
+** shell.c test_vfstrace.c sqlite3.c -ldl -lreadline -lncurses
16716
+**
16717
+** The gcc command above works on Linux and provides (in addition to the
16718
+** -vfstrace option) support for FTS3 and FTS4, RTREE, and command-line
16719
+** editing using the readline library. The command-line shell does not
16720
+** use threads so we added -DSQLITE_THREADSAFE=0 just to make the code
16721
+** run a little faster. For compiling on a Mac, you'll probably need
16722
+** to omit the -DHAVE_READLINE, the -lreadline, and the -lncurses options.
16723
+** The compilation could be simplified to just this:
16724
+**
16725
+** gcc -DSQLITE_ENABLE_VFSTRACE \
16726
+** shell.c test_vfstrace.c sqlite3.c -ldl -lpthread
16727
+**
16728
+** In this second example, all unnecessary options have been removed
16729
+** Note that since the code is now threadsafe, we had to add the -lpthread
16730
+** option to pull in the pthreads library.
16731
+**
16732
+** To cross-compile for windows using MinGW, a command like this might
16733
+** work:
16734
+**
16735
+** /opt/mingw/bin/i386-mingw32msvc-gcc -o sqlite3.exe -Os -I \
16736
+** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_VFSTRACE \
16737
+** shell.c test_vfstrace.c sqlite3.c
16738
+**
16739
+** Similar compiler commands will work on different systems. The key
16740
+** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that
16741
+** the shell.c source file will know to include the -vfstrace command-line
16742
+** option and (2) you must compile and link the three source files
16743
+** shell,c, test_vfstrace.c, and sqlite3.c.
16744
+*/
16745
+#include <stdlib.h>
16746
+#include <string.h>
16747
+/* #include "sqlite3.h" */
16748
+
16749
+/*
16750
+** An instance of this structure is attached to the each trace VFS to
16751
+** provide auxiliary information.
16752
+*/
16753
+typedef struct vfstrace_info vfstrace_info;
16754
+struct vfstrace_info {
16755
+ sqlite3_vfs *pRootVfs; /* The underlying real VFS */
16756
+ int (*xOut)(const char*, void*); /* Send output here */
16757
+ void *pOutArg; /* First argument to xOut */
16758
+ const char *zVfsName; /* Name of this trace-VFS */
16759
+ sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */
16760
+};
16761
+
16762
+/*
16763
+** The sqlite3_file object for the trace VFS
16764
+*/
16765
+typedef struct vfstrace_file vfstrace_file;
16766
+struct vfstrace_file {
16767
+ sqlite3_file base; /* Base class. Must be first */
16768
+ vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */
16769
+ const char *zFName; /* Base name of the file */
16770
+ sqlite3_file *pReal; /* The real underlying file */
16771
+};
16772
+
16773
+/*
16774
+** Method declarations for vfstrace_file.
16775
+*/
16776
+static int vfstraceClose(sqlite3_file*);
16777
+static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
16778
+static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64);
16779
+static int vfstraceTruncate(sqlite3_file*, sqlite3_int64 size);
16780
+static int vfstraceSync(sqlite3_file*, int flags);
16781
+static int vfstraceFileSize(sqlite3_file*, sqlite3_int64 *pSize);
16782
+static int vfstraceLock(sqlite3_file*, int);
16783
+static int vfstraceUnlock(sqlite3_file*, int);
16784
+static int vfstraceCheckReservedLock(sqlite3_file*, int *);
16785
+static int vfstraceFileControl(sqlite3_file*, int op, void *pArg);
16786
+static int vfstraceSectorSize(sqlite3_file*);
16787
+static int vfstraceDeviceCharacteristics(sqlite3_file*);
16788
+static int vfstraceShmLock(sqlite3_file*,int,int,int);
16789
+static int vfstraceShmMap(sqlite3_file*,int,int,int, void volatile **);
16790
+static void vfstraceShmBarrier(sqlite3_file*);
16791
+static int vfstraceShmUnmap(sqlite3_file*,int);
16792
+
16793
+/*
16794
+** Method declarations for vfstrace_vfs.
16795
+*/
16796
+static int vfstraceOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
16797
+static int vfstraceDelete(sqlite3_vfs*, const char *zName, int syncDir);
16798
+static int vfstraceAccess(sqlite3_vfs*, const char *zName, int flags, int *);
16799
+static int vfstraceFullPathname(sqlite3_vfs*, const char *zName, int, char *);
16800
+static void *vfstraceDlOpen(sqlite3_vfs*, const char *zFilename);
16801
+static void vfstraceDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
16802
+static void (*vfstraceDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
16803
+static void vfstraceDlClose(sqlite3_vfs*, void*);
16804
+static int vfstraceRandomness(sqlite3_vfs*, int nByte, char *zOut);
16805
+static int vfstraceSleep(sqlite3_vfs*, int microseconds);
16806
+static int vfstraceCurrentTime(sqlite3_vfs*, double*);
16807
+static int vfstraceGetLastError(sqlite3_vfs*, int, char*);
16808
+static int vfstraceCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
16809
+static int vfstraceSetSystemCall(sqlite3_vfs*,const char*, sqlite3_syscall_ptr);
16810
+static sqlite3_syscall_ptr vfstraceGetSystemCall(sqlite3_vfs*, const char *);
16811
+static const char *vfstraceNextSystemCall(sqlite3_vfs*, const char *zName);
16812
+
16813
+/*
16814
+** Return a pointer to the tail of the pathname. Examples:
16815
+**
16816
+** /home/drh/xyzzy.txt -> xyzzy.txt
16817
+** xyzzy.txt -> xyzzy.txt
16818
+*/
16819
+static const char *fileTail(const char *z){
16820
+ size_t i;
16821
+ if( z==0 ) return 0;
16822
+ i = strlen(z)-1;
16823
+ while( i>0 && z[i-1]!='/' ){ i--; }
16824
+ return &z[i];
16825
+}
16826
+
16827
+/*
16828
+** Send trace output defined by zFormat and subsequent arguments.
16829
+*/
16830
+static void vfstrace_printf(
16831
+ vfstrace_info *pInfo,
16832
+ const char *zFormat,
16833
+ ...
16834
+){
16835
+ va_list ap;
16836
+ char *zMsg;
16837
+ va_start(ap, zFormat);
16838
+ zMsg = sqlite3_vmprintf(zFormat, ap);
16839
+ va_end(ap);
16840
+ pInfo->xOut(zMsg, pInfo->pOutArg);
16841
+ sqlite3_free(zMsg);
16842
+}
16843
+
16844
+/*
16845
+** Try to convert an error code into a symbolic name for that error code.
16846
+*/
16847
+static const char *vfstrace_errcode_name(int rc ){
16848
+ const char *zVal = 0;
16849
+ switch( rc ){
16850
+ case SQLITE_OK: zVal = "SQLITE_OK"; break;
16851
+ case SQLITE_INTERNAL: zVal = "SQLITE_INTERNAL"; break;
16852
+ case SQLITE_ERROR: zVal = "SQLITE_ERROR"; break;
16853
+ case SQLITE_PERM: zVal = "SQLITE_PERM"; break;
16854
+ case SQLITE_ABORT: zVal = "SQLITE_ABORT"; break;
16855
+ case SQLITE_BUSY: zVal = "SQLITE_BUSY"; break;
16856
+ case SQLITE_LOCKED: zVal = "SQLITE_LOCKED"; break;
16857
+ case SQLITE_NOMEM: zVal = "SQLITE_NOMEM"; break;
16858
+ case SQLITE_READONLY: zVal = "SQLITE_READONLY"; break;
16859
+ case SQLITE_INTERRUPT: zVal = "SQLITE_INTERRUPT"; break;
16860
+ case SQLITE_IOERR: zVal = "SQLITE_IOERR"; break;
16861
+ case SQLITE_CORRUPT: zVal = "SQLITE_CORRUPT"; break;
16862
+ case SQLITE_NOTFOUND: zVal = "SQLITE_NOTFOUND"; break;
16863
+ case SQLITE_FULL: zVal = "SQLITE_FULL"; break;
16864
+ case SQLITE_CANTOPEN: zVal = "SQLITE_CANTOPEN"; break;
16865
+ case SQLITE_PROTOCOL: zVal = "SQLITE_PROTOCOL"; break;
16866
+ case SQLITE_EMPTY: zVal = "SQLITE_EMPTY"; break;
16867
+ case SQLITE_SCHEMA: zVal = "SQLITE_SCHEMA"; break;
16868
+ case SQLITE_TOOBIG: zVal = "SQLITE_TOOBIG"; break;
16869
+ case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT"; break;
16870
+ case SQLITE_MISMATCH: zVal = "SQLITE_MISMATCH"; break;
16871
+ case SQLITE_MISUSE: zVal = "SQLITE_MISUSE"; break;
16872
+ case SQLITE_NOLFS: zVal = "SQLITE_NOLFS"; break;
16873
+ case SQLITE_IOERR_READ: zVal = "SQLITE_IOERR_READ"; break;
16874
+ case SQLITE_IOERR_SHORT_READ: zVal = "SQLITE_IOERR_SHORT_READ"; break;
16875
+ case SQLITE_IOERR_WRITE: zVal = "SQLITE_IOERR_WRITE"; break;
16876
+ case SQLITE_IOERR_FSYNC: zVal = "SQLITE_IOERR_FSYNC"; break;
16877
+ case SQLITE_IOERR_DIR_FSYNC: zVal = "SQLITE_IOERR_DIR_FSYNC"; break;
16878
+ case SQLITE_IOERR_TRUNCATE: zVal = "SQLITE_IOERR_TRUNCATE"; break;
16879
+ case SQLITE_IOERR_FSTAT: zVal = "SQLITE_IOERR_FSTAT"; break;
16880
+ case SQLITE_IOERR_UNLOCK: zVal = "SQLITE_IOERR_UNLOCK"; break;
16881
+ case SQLITE_IOERR_RDLOCK: zVal = "SQLITE_IOERR_RDLOCK"; break;
16882
+ case SQLITE_IOERR_DELETE: zVal = "SQLITE_IOERR_DELETE"; break;
16883
+ case SQLITE_IOERR_BLOCKED: zVal = "SQLITE_IOERR_BLOCKED"; break;
16884
+ case SQLITE_IOERR_NOMEM: zVal = "SQLITE_IOERR_NOMEM"; break;
16885
+ case SQLITE_IOERR_ACCESS: zVal = "SQLITE_IOERR_ACCESS"; break;
16886
+ case SQLITE_IOERR_CHECKRESERVEDLOCK:
16887
+ zVal = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
16888
+ case SQLITE_IOERR_LOCK: zVal = "SQLITE_IOERR_LOCK"; break;
16889
+ case SQLITE_IOERR_CLOSE: zVal = "SQLITE_IOERR_CLOSE"; break;
16890
+ case SQLITE_IOERR_DIR_CLOSE: zVal = "SQLITE_IOERR_DIR_CLOSE"; break;
16891
+ case SQLITE_IOERR_SHMOPEN: zVal = "SQLITE_IOERR_SHMOPEN"; break;
16892
+ case SQLITE_IOERR_SHMSIZE: zVal = "SQLITE_IOERR_SHMSIZE"; break;
16893
+ case SQLITE_IOERR_SHMLOCK: zVal = "SQLITE_IOERR_SHMLOCK"; break;
16894
+ case SQLITE_IOERR_SHMMAP: zVal = "SQLITE_IOERR_SHMMAP"; break;
16895
+ case SQLITE_IOERR_SEEK: zVal = "SQLITE_IOERR_SEEK"; break;
16896
+ case SQLITE_IOERR_GETTEMPPATH: zVal = "SQLITE_IOERR_GETTEMPPATH"; break;
16897
+ case SQLITE_IOERR_CONVPATH: zVal = "SQLITE_IOERR_CONVPATH"; break;
16898
+ case SQLITE_READONLY_DBMOVED: zVal = "SQLITE_READONLY_DBMOVED"; break;
16899
+ case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break;
16900
+ case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break;
16901
+ case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break;
16902
+ }
16903
+ return zVal;
16904
+}
16905
+
16906
+/*
16907
+** Convert value rc into a string and print it using zFormat. zFormat
16908
+** should have exactly one %s
16909
+*/
16910
+static void vfstrace_print_errcode(
16911
+ vfstrace_info *pInfo,
16912
+ const char *zFormat,
16913
+ int rc
16914
+){
16915
+ const char *zVal;
16916
+ char zBuf[50];
16917
+ zVal = vfstrace_errcode_name(rc);
16918
+ if( zVal==0 ){
16919
+ zVal = vfstrace_errcode_name(rc&0xff);
16920
+ if( zVal ){
16921
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%s | 0x%x", zVal, rc&0xffff00);
16922
+ }else{
16923
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%d (0x%x)", rc, rc);
16924
+ }
16925
+ zVal = zBuf;
16926
+ }
16927
+ vfstrace_printf(pInfo, zFormat, zVal);
16928
+}
16929
+
16930
+/*
16931
+** Append to a buffer.
16932
+*/
16933
+static void strappend(char *z, int *pI, const char *zAppend){
16934
+ int i = *pI;
16935
+ while( zAppend[0] ){ z[i++] = *(zAppend++); }
16936
+ z[i] = 0;
16937
+ *pI = i;
16938
+}
16939
+
16940
+/*
16941
+** Close an vfstrace-file.
16942
+*/
16943
+static int vfstraceClose(sqlite3_file *pFile){
16944
+ vfstrace_file *p = (vfstrace_file *)pFile;
16945
+ vfstrace_info *pInfo = p->pInfo;
16946
+ int rc;
16947
+ vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName);
16948
+ rc = p->pReal->pMethods->xClose(p->pReal);
16949
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16950
+ if( rc==SQLITE_OK ){
16951
+ sqlite3_free((void*)p->base.pMethods);
16952
+ p->base.pMethods = 0;
16953
+ }
16954
+ return rc;
16955
+}
16956
+
16957
+/*
16958
+** Read data from an vfstrace-file.
16959
+*/
16960
+static int vfstraceRead(
16961
+ sqlite3_file *pFile,
16962
+ void *zBuf,
16963
+ int iAmt,
16964
+ sqlite_int64 iOfst
16965
+){
16966
+ vfstrace_file *p = (vfstrace_file *)pFile;
16967
+ vfstrace_info *pInfo = p->pInfo;
16968
+ int rc;
16969
+ vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)",
16970
+ pInfo->zVfsName, p->zFName, iAmt, iOfst);
16971
+ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
16972
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16973
+ return rc;
16974
+}
16975
+
16976
+/*
16977
+** Write data to an vfstrace-file.
16978
+*/
16979
+static int vfstraceWrite(
16980
+ sqlite3_file *pFile,
16981
+ const void *zBuf,
16982
+ int iAmt,
16983
+ sqlite_int64 iOfst
16984
+){
16985
+ vfstrace_file *p = (vfstrace_file *)pFile;
16986
+ vfstrace_info *pInfo = p->pInfo;
16987
+ int rc;
16988
+ vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)",
16989
+ pInfo->zVfsName, p->zFName, iAmt, iOfst);
16990
+ rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
16991
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16992
+ return rc;
16993
+}
16994
+
16995
+/*
16996
+** Truncate an vfstrace-file.
16997
+*/
16998
+static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){
16999
+ vfstrace_file *p = (vfstrace_file *)pFile;
17000
+ vfstrace_info *pInfo = p->pInfo;
17001
+ int rc;
17002
+ vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName,
17003
+ size);
17004
+ rc = p->pReal->pMethods->xTruncate(p->pReal, size);
17005
+ vfstrace_printf(pInfo, " -> %d\n", rc);
17006
+ return rc;
17007
+}
17008
+
17009
+/*
17010
+** Sync an vfstrace-file.
17011
+*/
17012
+static int vfstraceSync(sqlite3_file *pFile, int flags){
17013
+ vfstrace_file *p = (vfstrace_file *)pFile;
17014
+ vfstrace_info *pInfo = p->pInfo;
17015
+ int rc;
17016
+ int i;
17017
+ char zBuf[100];
17018
+ memcpy(zBuf, "|0", 3);
17019
+ i = 0;
17020
+ if( flags & SQLITE_SYNC_FULL ) strappend(zBuf, &i, "|FULL");
17021
+ else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL");
17022
+ if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY");
17023
+ if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
17024
+ sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
17025
+ }
17026
+ vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
17027
+ &zBuf[1]);
17028
+ rc = p->pReal->pMethods->xSync(p->pReal, flags);
17029
+ vfstrace_printf(pInfo, " -> %d\n", rc);
17030
+ return rc;
17031
+}
17032
+
17033
+/*
17034
+** Return the current file-size of an vfstrace-file.
17035
+*/
17036
+static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
17037
+ vfstrace_file *p = (vfstrace_file *)pFile;
17038
+ vfstrace_info *pInfo = p->pInfo;
17039
+ int rc;
17040
+ vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName);
17041
+ rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
17042
+ vfstrace_print_errcode(pInfo, " -> %s,", rc);
17043
+ vfstrace_printf(pInfo, " size=%lld\n", *pSize);
17044
+ return rc;
17045
+}
17046
+
17047
+/*
17048
+** Return the name of a lock.
17049
+*/
17050
+static const char *lockName(int eLock){
17051
+ const char *azLockNames[] = {
17052
+ "NONE", "SHARED", "RESERVED", "PENDING", "EXCLUSIVE"
17053
+ };
17054
+ if( eLock<0 || eLock>=sizeof(azLockNames)/sizeof(azLockNames[0]) ){
17055
+ return "???";
17056
+ }else{
17057
+ return azLockNames[eLock];
17058
+ }
17059
+}
17060
+
17061
+/*
17062
+** Lock an vfstrace-file.
17063
+*/
17064
+static int vfstraceLock(sqlite3_file *pFile, int eLock){
17065
+ vfstrace_file *p = (vfstrace_file *)pFile;
17066
+ vfstrace_info *pInfo = p->pInfo;
17067
+ int rc;
17068
+ vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName,
17069
+ lockName(eLock));
17070
+ rc = p->pReal->pMethods->xLock(p->pReal, eLock);
17071
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17072
+ return rc;
17073
+}
17074
+
17075
+/*
17076
+** Unlock an vfstrace-file.
17077
+*/
17078
+static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
17079
+ vfstrace_file *p = (vfstrace_file *)pFile;
17080
+ vfstrace_info *pInfo = p->pInfo;
17081
+ int rc;
17082
+ vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
17083
+ lockName(eLock));
17084
+ rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
17085
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17086
+ return rc;
17087
+}
17088
+
17089
+/*
17090
+** Check if another file-handle holds a RESERVED lock on an vfstrace-file.
17091
+*/
17092
+static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){
17093
+ vfstrace_file *p = (vfstrace_file *)pFile;
17094
+ vfstrace_info *pInfo = p->pInfo;
17095
+ int rc;
17096
+ vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)",
17097
+ pInfo->zVfsName, p->zFName);
17098
+ rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
17099
+ vfstrace_print_errcode(pInfo, " -> %s", rc);
17100
+ vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
17101
+ return rc;
17102
+}
17103
+
17104
+/*
17105
+** File control method. For custom operations on an vfstrace-file.
17106
+*/
17107
+static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
17108
+ vfstrace_file *p = (vfstrace_file *)pFile;
17109
+ vfstrace_info *pInfo = p->pInfo;
17110
+ int rc;
17111
+ char zBuf[100];
17112
+ char zBuf2[100];
17113
+ char *zOp;
17114
+ char *zRVal = 0;
17115
+ switch( op ){
17116
+ case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
17117
+ case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
17118
+ case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break;
17119
+ case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break;
17120
+ case SQLITE_FCNTL_SIZE_HINT: {
17121
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "SIZE_HINT,%lld",
17122
+ *(sqlite3_int64*)pArg);
17123
+ zOp = zBuf;
17124
+ break;
17125
+ }
17126
+ case SQLITE_FCNTL_CHUNK_SIZE: {
17127
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "CHUNK_SIZE,%d", *(int*)pArg);
17128
+ zOp = zBuf;
17129
+ break;
17130
+ }
17131
+ case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break;
17132
+ case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break;
17133
+ case SQLITE_FCNTL_PERSIST_WAL: {
17134
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "PERSIST_WAL,%d", *(int*)pArg);
17135
+ zOp = zBuf;
17136
+ break;
17137
+ }
17138
+ case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
17139
+ case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
17140
+ case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
17141
+ case SQLITE_FCNTL_PRAGMA: {
17142
+ const char *const* a = (const char*const*)pArg;
17143
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
17144
+ zOp = zBuf;
17145
+ break;
17146
+ }
17147
+ case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break;
17148
+ case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break;
17149
+ case SQLITE_FCNTL_MMAP_SIZE: {
17150
+ sqlite3_int64 iMMap = *(sqlite3_int64*)pArg;
17151
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "MMAP_SIZE,%lld",iMMap);
17152
+ zOp = zBuf;
17153
+ break;
17154
+ }
17155
+ case SQLITE_FCNTL_TRACE: zOp = "TRACE"; break;
17156
+ case SQLITE_FCNTL_HAS_MOVED: zOp = "HAS_MOVED"; break;
17157
+ case SQLITE_FCNTL_SYNC: zOp = "SYNC"; break;
17158
+ case SQLITE_FCNTL_COMMIT_PHASETWO: zOp = "COMMIT_PHASETWO"; break;
17159
+ case SQLITE_FCNTL_WIN32_SET_HANDLE: zOp = "WIN32_SET_HANDLE"; break;
17160
+ case SQLITE_FCNTL_WAL_BLOCK: zOp = "WAL_BLOCK"; break;
17161
+ case SQLITE_FCNTL_ZIPVFS: zOp = "ZIPVFS"; break;
17162
+ case SQLITE_FCNTL_RBU: zOp = "RBU"; break;
17163
+ case SQLITE_FCNTL_VFS_POINTER: zOp = "VFS_POINTER"; break;
17164
+ case SQLITE_FCNTL_JOURNAL_POINTER: zOp = "JOURNAL_POINTER"; break;
17165
+ case SQLITE_FCNTL_WIN32_GET_HANDLE: zOp = "WIN32_GET_HANDLE"; break;
17166
+ case SQLITE_FCNTL_PDB: zOp = "PDB"; break;
17167
+ case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: zOp = "BEGIN_ATOMIC_WRITE"; break;
17168
+ case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: zOp = "COMMIT_ATOMIC_WRITE"; break;
17169
+ case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
17170
+ zOp = "ROLLBACK_ATOMIC_WRITE";
17171
+ break;
17172
+ }
17173
+ case SQLITE_FCNTL_LOCK_TIMEOUT: {
17174
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "LOCK_TIMEOUT,%d", *(int*)pArg);
17175
+ zOp = zBuf;
17176
+ break;
17177
+ }
17178
+ case SQLITE_FCNTL_DATA_VERSION: zOp = "DATA_VERSION"; break;
17179
+ case SQLITE_FCNTL_SIZE_LIMIT: zOp = "SIZE_LIMIT"; break;
17180
+ case SQLITE_FCNTL_CKPT_DONE: zOp = "CKPT_DONE"; break;
17181
+ case SQLITE_FCNTL_RESERVE_BYTES: zOp = "RESERVED_BYTES"; break;
17182
+ case SQLITE_FCNTL_CKPT_START: zOp = "CKPT_START"; break;
17183
+ case SQLITE_FCNTL_EXTERNAL_READER: zOp = "EXTERNAL_READER"; break;
17184
+ case SQLITE_FCNTL_CKSM_FILE: zOp = "CKSM_FILE"; break;
17185
+ case SQLITE_FCNTL_RESET_CACHE: zOp = "RESET_CACHE"; break;
17186
+ case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
17187
+ default: {
17188
+ sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op);
17189
+ zOp = zBuf;
17190
+ break;
17191
+ }
17192
+ }
17193
+ vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)",
17194
+ pInfo->zVfsName, p->zFName, zOp);
17195
+ rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
17196
+ if( rc==SQLITE_OK ){
17197
+ switch( op ){
17198
+ case SQLITE_FCNTL_VFSNAME: {
17199
+ *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
17200
+ pInfo->zVfsName, *(char**)pArg);
17201
+ zRVal = *(char**)pArg;
17202
+ break;
17203
+ }
17204
+ case SQLITE_FCNTL_MMAP_SIZE: {
17205
+ sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%lld", *(sqlite3_int64*)pArg);
17206
+ zRVal = zBuf2;
17207
+ break;
17208
+ }
17209
+ case SQLITE_FCNTL_HAS_MOVED:
17210
+ case SQLITE_FCNTL_PERSIST_WAL: {
17211
+ sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%d", *(int*)pArg);
17212
+ zRVal = zBuf2;
17213
+ break;
17214
+ }
17215
+ case SQLITE_FCNTL_PRAGMA:
17216
+ case SQLITE_FCNTL_TEMPFILENAME: {
17217
+ zRVal = *(char**)pArg;
17218
+ break;
17219
+ }
17220
+ }
17221
+ }
17222
+ if( zRVal ){
17223
+ vfstrace_print_errcode(pInfo, " -> %s", rc);
17224
+ vfstrace_printf(pInfo, ", %s\n", zRVal);
17225
+ }else{
17226
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17227
+ }
17228
+ return rc;
17229
+}
17230
+
17231
+/*
17232
+** Return the sector-size in bytes for an vfstrace-file.
17233
+*/
17234
+static int vfstraceSectorSize(sqlite3_file *pFile){
17235
+ vfstrace_file *p = (vfstrace_file *)pFile;
17236
+ vfstrace_info *pInfo = p->pInfo;
17237
+ int rc;
17238
+ vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName);
17239
+ rc = p->pReal->pMethods->xSectorSize(p->pReal);
17240
+ vfstrace_printf(pInfo, " -> %d\n", rc);
17241
+ return rc;
17242
+}
17243
+
17244
+/*
17245
+** Return the device characteristic flags supported by an vfstrace-file.
17246
+*/
17247
+static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
17248
+ vfstrace_file *p = (vfstrace_file *)pFile;
17249
+ vfstrace_info *pInfo = p->pInfo;
17250
+ int rc;
17251
+ vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)",
17252
+ pInfo->zVfsName, p->zFName);
17253
+ rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
17254
+ vfstrace_printf(pInfo, " -> 0x%08x\n", rc);
17255
+ return rc;
17256
+}
17257
+
17258
+/*
17259
+** Shared-memory operations.
17260
+*/
17261
+static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
17262
+ vfstrace_file *p = (vfstrace_file *)pFile;
17263
+ vfstrace_info *pInfo = p->pInfo;
17264
+ int rc;
17265
+ char zLck[100];
17266
+ int i = 0;
17267
+ memcpy(zLck, "|0", 3);
17268
+ if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK");
17269
+ if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK");
17270
+ if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED");
17271
+ if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE");
17272
+ if( flags & ~(0xf) ){
17273
+ sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
17274
+ }
17275
+ vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
17276
+ pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
17277
+ rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
17278
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17279
+ return rc;
17280
+}
17281
+static int vfstraceShmMap(
17282
+ sqlite3_file *pFile,
17283
+ int iRegion,
17284
+ int szRegion,
17285
+ int isWrite,
17286
+ void volatile **pp
17287
+){
17288
+ vfstrace_file *p = (vfstrace_file *)pFile;
17289
+ vfstrace_info *pInfo = p->pInfo;
17290
+ int rc;
17291
+ vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)",
17292
+ pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite);
17293
+ rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
17294
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17295
+ return rc;
17296
+}
17297
+static void vfstraceShmBarrier(sqlite3_file *pFile){
17298
+ vfstrace_file *p = (vfstrace_file *)pFile;
17299
+ vfstrace_info *pInfo = p->pInfo;
17300
+ vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName);
17301
+ p->pReal->pMethods->xShmBarrier(p->pReal);
17302
+}
17303
+static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){
17304
+ vfstrace_file *p = (vfstrace_file *)pFile;
17305
+ vfstrace_info *pInfo = p->pInfo;
17306
+ int rc;
17307
+ vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
17308
+ pInfo->zVfsName, p->zFName, delFlag);
17309
+ rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
17310
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17311
+ return rc;
17312
+}
17313
+
17314
+
17315
+
17316
+/*
17317
+** Open an vfstrace file handle.
17318
+*/
17319
+static int vfstraceOpen(
17320
+ sqlite3_vfs *pVfs,
17321
+ const char *zName,
17322
+ sqlite3_file *pFile,
17323
+ int flags,
17324
+ int *pOutFlags
17325
+){
17326
+ int rc;
17327
+ vfstrace_file *p = (vfstrace_file *)pFile;
17328
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17329
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17330
+ p->pInfo = pInfo;
17331
+ p->zFName = zName ? fileTail(zName) : "<temp>";
17332
+ p->pReal = (sqlite3_file *)&p[1];
17333
+ rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags);
17334
+ vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
17335
+ pInfo->zVfsName, p->zFName, flags);
17336
+ if( p->pReal->pMethods ){
17337
+ sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) );
17338
+ const sqlite3_io_methods *pSub = p->pReal->pMethods;
17339
+ memset(pNew, 0, sizeof(*pNew));
17340
+ pNew->iVersion = pSub->iVersion;
17341
+ pNew->xClose = vfstraceClose;
17342
+ pNew->xRead = vfstraceRead;
17343
+ pNew->xWrite = vfstraceWrite;
17344
+ pNew->xTruncate = vfstraceTruncate;
17345
+ pNew->xSync = vfstraceSync;
17346
+ pNew->xFileSize = vfstraceFileSize;
17347
+ pNew->xLock = vfstraceLock;
17348
+ pNew->xUnlock = vfstraceUnlock;
17349
+ pNew->xCheckReservedLock = vfstraceCheckReservedLock;
17350
+ pNew->xFileControl = vfstraceFileControl;
17351
+ pNew->xSectorSize = vfstraceSectorSize;
17352
+ pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics;
17353
+ if( pNew->iVersion>=2 ){
17354
+ pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0;
17355
+ pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0;
17356
+ pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0;
17357
+ pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0;
17358
+ }
17359
+ pFile->pMethods = pNew;
17360
+ }
17361
+ vfstrace_print_errcode(pInfo, " -> %s", rc);
17362
+ if( pOutFlags ){
17363
+ vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags);
17364
+ }else{
17365
+ vfstrace_printf(pInfo, "\n");
17366
+ }
17367
+ return rc;
17368
+}
17369
+
17370
+/*
17371
+** Delete the file located at zPath. If the dirSync argument is true,
17372
+** ensure the file-system modifications are synced to disk before
17373
+** returning.
17374
+*/
17375
+static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
17376
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17377
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17378
+ int rc;
17379
+ vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
17380
+ pInfo->zVfsName, zPath, dirSync);
17381
+ rc = pRoot->xDelete(pRoot, zPath, dirSync);
17382
+ vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17383
+ return rc;
17384
+}
17385
+
17386
+/*
17387
+** Test for access permissions. Return true if the requested permission
17388
+** is available, or false otherwise.
17389
+*/
17390
+static int vfstraceAccess(
17391
+ sqlite3_vfs *pVfs,
17392
+ const char *zPath,
17393
+ int flags,
17394
+ int *pResOut
17395
+){
17396
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17397
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17398
+ int rc;
17399
+ vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)",
17400
+ pInfo->zVfsName, zPath, flags);
17401
+ rc = pRoot->xAccess(pRoot, zPath, flags, pResOut);
17402
+ vfstrace_print_errcode(pInfo, " -> %s", rc);
17403
+ vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
17404
+ return rc;
17405
+}
17406
+
17407
+/*
17408
+** Populate buffer zOut with the full canonical pathname corresponding
17409
+** to the pathname in zPath. zOut is guaranteed to point to a buffer
17410
+** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
17411
+*/
17412
+static int vfstraceFullPathname(
17413
+ sqlite3_vfs *pVfs,
17414
+ const char *zPath,
17415
+ int nOut,
17416
+ char *zOut
17417
+){
17418
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17419
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17420
+ int rc;
17421
+ vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")",
17422
+ pInfo->zVfsName, zPath);
17423
+ rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut);
17424
+ vfstrace_print_errcode(pInfo, " -> %s", rc);
17425
+ vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut);
17426
+ return rc;
17427
+}
17428
+
17429
+/*
17430
+** Open the dynamic library located at zPath and return a handle.
17431
+*/
17432
+static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
17433
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17434
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17435
+ vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath);
17436
+ return pRoot->xDlOpen(pRoot, zPath);
17437
+}
17438
+
17439
+/*
17440
+** Populate the buffer zErrMsg (size nByte bytes) with a human readable
17441
+** utf-8 string describing the most recent error encountered associated
17442
+** with dynamic libraries.
17443
+*/
17444
+static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
17445
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17446
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17447
+ vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte);
17448
+ pRoot->xDlError(pRoot, nByte, zErrMsg);
17449
+ vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg);
17450
+}
17451
+
17452
+/*
17453
+** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
17454
+*/
17455
+static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){
17456
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17457
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17458
+ vfstrace_printf(pInfo, "%s.xDlSym(\"%s\")\n", pInfo->zVfsName, zSym);
17459
+ return pRoot->xDlSym(pRoot, p, zSym);
17460
+}
17461
+
17462
+/*
17463
+** Close the dynamic library handle pHandle.
17464
+*/
17465
+static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
17466
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17467
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17468
+ vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
17469
+ pRoot->xDlClose(pRoot, pHandle);
17470
+}
17471
+
17472
+/*
17473
+** Populate the buffer pointed to by zBufOut with nByte bytes of
17474
+** random data.
17475
+*/
17476
+static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
17477
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17478
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17479
+ vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte);
17480
+ return pRoot->xRandomness(pRoot, nByte, zBufOut);
17481
+}
17482
+
17483
+/*
17484
+** Sleep for nMicro microseconds. Return the number of microseconds
17485
+** actually slept.
17486
+*/
17487
+static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
17488
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17489
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17490
+ return pRoot->xSleep(pRoot, nMicro);
17491
+}
17492
+
17493
+/*
17494
+** Return the current time as a Julian Day number in *pTimeOut.
17495
+*/
17496
+static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
17497
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17498
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17499
+ return pRoot->xCurrentTime(pRoot, pTimeOut);
17500
+}
17501
+static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
17502
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17503
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17504
+ return pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
17505
+}
17506
+
17507
+/*
17508
+** Return th3 most recent error code and message
17509
+*/
17510
+static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){
17511
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17512
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17513
+ return pRoot->xGetLastError(pRoot, iErr, zErr);
17514
+}
17515
+
17516
+/*
17517
+** Override system calls.
17518
+*/
17519
+static int vfstraceSetSystemCall(
17520
+ sqlite3_vfs *pVfs,
17521
+ const char *zName,
17522
+ sqlite3_syscall_ptr pFunc
17523
+){
17524
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17525
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17526
+ return pRoot->xSetSystemCall(pRoot, zName, pFunc);
17527
+}
17528
+static sqlite3_syscall_ptr vfstraceGetSystemCall(
17529
+ sqlite3_vfs *pVfs,
17530
+ const char *zName
17531
+){
17532
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17533
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17534
+ return pRoot->xGetSystemCall(pRoot, zName);
17535
+}
17536
+static const char *vfstraceNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
17537
+ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17538
+ sqlite3_vfs *pRoot = pInfo->pRootVfs;
17539
+ return pRoot->xNextSystemCall(pRoot, zName);
17540
+}
17541
+
17542
+
17543
+/*
17544
+** Clients invoke this routine to construct a new trace-vfs shim.
17545
+**
17546
+** Return SQLITE_OK on success.
17547
+**
17548
+** SQLITE_NOMEM is returned in the case of a memory allocation error.
17549
+** SQLITE_NOTFOUND is returned if zOldVfsName does not exist.
17550
+*/
17551
+int vfstrace_register(
17552
+ const char *zTraceName, /* Name of the newly constructed VFS */
17553
+ const char *zOldVfsName, /* Name of the underlying VFS */
17554
+ int (*xOut)(const char*,void*), /* Output routine. ex: fputs */
17555
+ void *pOutArg, /* 2nd argument to xOut. ex: stderr */
17556
+ int makeDefault /* True to make the new VFS the default */
17557
+){
17558
+ sqlite3_vfs *pNew;
17559
+ sqlite3_vfs *pRoot;
17560
+ vfstrace_info *pInfo;
17561
+ size_t nName;
17562
+ size_t nByte;
17563
+
17564
+ pRoot = sqlite3_vfs_find(zOldVfsName);
17565
+ if( pRoot==0 ) return SQLITE_NOTFOUND;
17566
+ nName = strlen(zTraceName);
17567
+ nByte = sizeof(*pNew) + sizeof(*pInfo) + nName + 1;
17568
+ pNew = sqlite3_malloc64( nByte );
17569
+ if( pNew==0 ) return SQLITE_NOMEM;
17570
+ memset(pNew, 0, nByte);
17571
+ pInfo = (vfstrace_info*)&pNew[1];
17572
+ pNew->iVersion = pRoot->iVersion;
17573
+ pNew->szOsFile = pRoot->szOsFile + sizeof(vfstrace_file);
17574
+ pNew->mxPathname = pRoot->mxPathname;
17575
+ pNew->zName = (char*)&pInfo[1];
17576
+ memcpy((char*)&pInfo[1], zTraceName, nName+1);
17577
+ pNew->pAppData = pInfo;
17578
+ pNew->xOpen = vfstraceOpen;
17579
+ pNew->xDelete = vfstraceDelete;
17580
+ pNew->xAccess = vfstraceAccess;
17581
+ pNew->xFullPathname = vfstraceFullPathname;
17582
+ pNew->xDlOpen = pRoot->xDlOpen==0 ? 0 : vfstraceDlOpen;
17583
+ pNew->xDlError = pRoot->xDlError==0 ? 0 : vfstraceDlError;
17584
+ pNew->xDlSym = pRoot->xDlSym==0 ? 0 : vfstraceDlSym;
17585
+ pNew->xDlClose = pRoot->xDlClose==0 ? 0 : vfstraceDlClose;
17586
+ pNew->xRandomness = vfstraceRandomness;
17587
+ pNew->xSleep = vfstraceSleep;
17588
+ pNew->xCurrentTime = vfstraceCurrentTime;
17589
+ pNew->xGetLastError = pRoot->xGetLastError==0 ? 0 : vfstraceGetLastError;
17590
+ if( pNew->iVersion>=2 ){
17591
+ pNew->xCurrentTimeInt64 = pRoot->xCurrentTimeInt64==0 ? 0 :
17592
+ vfstraceCurrentTimeInt64;
17593
+ if( pNew->iVersion>=3 ){
17594
+ pNew->xSetSystemCall = pRoot->xSetSystemCall==0 ? 0 :
17595
+ vfstraceSetSystemCall;
17596
+ pNew->xGetSystemCall = pRoot->xGetSystemCall==0 ? 0 :
17597
+ vfstraceGetSystemCall;
17598
+ pNew->xNextSystemCall = pRoot->xNextSystemCall==0 ? 0 :
17599
+ vfstraceNextSystemCall;
17600
+ }
17601
+ }
17602
+ pInfo->pRootVfs = pRoot;
17603
+ pInfo->xOut = xOut;
17604
+ pInfo->pOutArg = pOutArg;
17605
+ pInfo->zVfsName = pNew->zName;
17606
+ pInfo->pTraceVfs = pNew;
17607
+ vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n",
17608
+ pInfo->zVfsName, pRoot->zName);
17609
+ return sqlite3_vfs_register(pNew, makeDefault);
17610
+}
17611
+
17612
+/*
17613
+** Look for the named VFS. If it is a TRACEVFS, then unregister it
17614
+** and delete it.
17615
+*/
17616
+void vfstrace_unregister(const char *zTraceName){
17617
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zTraceName);
17618
+ if( pVfs==0 ) return;
17619
+ if( pVfs->xOpen!=vfstraceOpen ) return;
17620
+ sqlite3_vfs_unregister(pVfs);
17621
+ sqlite3_free(pVfs);
17622
+}
17623
+
17624
+/************************* End ../ext/misc/vfstrace.c ********************/
1621617625
1621717626
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
1621817627
#define SQLITE_SHELL_HAVE_RECOVER 1
1621917628
#else
1622017629
#define SQLITE_SHELL_HAVE_RECOVER 0
@@ -24511,10 +25920,11 @@
2451125920
}
2451225921
2451325922
#ifndef SQLITE_OMIT_LOAD_EXTENSION
2451425923
sqlite3_enable_load_extension(p->db, 1);
2451525924
#endif
25925
+ sqlite3_sha_init(p->db, 0, 0);
2451625926
sqlite3_shathree_init(p->db, 0, 0);
2451725927
sqlite3_uint_init(p->db, 0, 0);
2451825928
sqlite3_stmtrand_init(p->db, 0, 0);
2451925929
sqlite3_decimal_init(p->db, 0, 0);
2452025930
sqlite3_percentile_init(p->db, 0, 0);
@@ -31374,13 +32784,11 @@
3137432784
" -table set output mode to 'table'\n"
3137532785
" -tabs set output mode to 'tabs'\n"
3137632786
" -unsafe-testing allow unsafe commands and modes for testing\n"
3137732787
" -version show SQLite version\n"
3137832788
" -vfs NAME use NAME as the default VFS\n"
31379
-#ifdef SQLITE_ENABLE_VFSTRACE
3138032789
" -vfstrace enable tracing of all VFS calls\n"
31381
-#endif
3138232790
#ifdef SQLITE_HAVE_ZLIB
3138332791
" -zip open the file as a ZIP Archive\n"
3138432792
#endif
3138532793
;
3138632794
static void usage(int showDetail){
@@ -31502,10 +32910,11 @@
3150232910
int rc = 0;
3150332911
int warnInmemoryDb = 0;
3150432912
int readStdin = 1;
3150532913
int nCmd = 0;
3150632914
int nOptsEnd = argc;
32915
+ int bEnableVfstrace = 0;
3150732916
char **azCmd = 0;
3150832917
const char *zVfs = 0; /* Value of -vfs command-line option */
3150932918
#if !SQLITE_SHELL_IS_UTF8
3151032919
char **argvToFree = 0;
3151132920
int argcToFree = 0;
@@ -31696,21 +33105,13 @@
3169633105
switch( n ){
3169733106
case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break;
3169833107
case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break;
3169933108
default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break;
3170033109
}
31701
-#ifdef SQLITE_ENABLE_VFSTRACE
3170233110
}else if( cli_strcmp(z,"-vfstrace")==0 ){
31703
- extern int vfstrace_register(
31704
- const char *zTraceName,
31705
- const char *zOldVfsName,
31706
- int (*xOut)(const char*,void*),
31707
- void *pOutArg,
31708
- int makeDefault
31709
- );
3171033111
vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
31711
-#endif
33112
+ bEnableVfstrace = 1;
3171233113
#ifdef SQLITE_ENABLE_MULTIPLEX
3171333114
}else if( cli_strcmp(z,"-multiplex")==0 ){
3171433115
extern int sqlite3_multiplex_initialize(const char*,int);
3171533116
sqlite3_multiplex_initialize(0, 1);
3171633117
#endif
@@ -31762,11 +33163,11 @@
3176233163
}else if( cli_strcmp(z,"-safe")==0 ){
3176333164
/* no-op - catch this on the second pass */
3176433165
}
3176533166
}
3176633167
#ifndef SQLITE_SHELL_FIDDLE
31767
- verify_uninitialized();
33168
+ if( !bEnableVfstrace ) verify_uninitialized();
3176833169
#endif
3176933170
3177033171
3177133172
#ifdef SQLITE_SHELL_INIT_PROC
3177233173
{
@@ -31951,14 +33352,12 @@
3195133352
}else if( cli_strcmp(z,"-sorterref")==0 ){
3195233353
i++;
3195333354
#endif
3195433355
}else if( cli_strcmp(z,"-vfs")==0 ){
3195533356
i++;
31956
-#ifdef SQLITE_ENABLE_VFSTRACE
3195733357
}else if( cli_strcmp(z,"-vfstrace")==0 ){
3195833358
i++;
31959
-#endif
3196033359
#ifdef SQLITE_ENABLE_MULTIPLEX
3196133360
}else if( cli_strcmp(z,"-multiplex")==0 ){
3196233361
i++;
3196333362
#endif
3196433363
}else if( cli_strcmp(z,"-help")==0 ){
@@ -32122,10 +33521,13 @@
3212233521
free(data.colWidth);
3212333522
free(data.zNonce);
3212433523
/* Clear the global data structure so that valgrind will detect memory
3212533524
** leaks */
3212633525
memset(&data, 0, sizeof(data));
33526
+ if( bEnableVfstrace ){
33527
+ vfstrace_unregister("trace");
33528
+ }
3212733529
#ifdef SQLITE_DEBUG
3212833530
if( sqlite3_memory_used()>mem_main_enter ){
3212933531
eputf("Memory leaked: %u bytes\n",
3213033532
(unsigned int)(sqlite3_memory_used()-mem_main_enter));
3213133533
}
3213233534
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1212,10 +1212,14 @@
1212 ++rv;
1213 }
1214 return rv;
1215 }
1216
 
 
 
 
1217 SQLITE_INTERNAL_LINKAGE char *
1218 cfGets(char *cBuf, int n, FILE *pf){
1219 int nci = 0;
1220 struct FileAltIds fai = altIdsOfFile(pf);
1221 int fmode = _setmode(fai.fd, _O_BINARY);
@@ -1222,11 +1226,14 @@
1222 BOOL eatCR = (fmode & _O_TEXT)!=0;
1223 _setmode(fai.fd, fmode);
1224 while( nci < n-1 ){
1225 DWORD nr;
1226 if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
1227 if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
 
 
 
1228 }
1229 if( nci < n ) cBuf[nci] = 0;
1230 return (nci>0)? cBuf : 0;
1231 }
1232 # else
@@ -3783,10 +3790,422 @@
3783 }
3784 return rc;
3785 }
3786
3787 /************************* End ../ext/misc/shathree.c ********************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3788 /************************* Begin ../ext/misc/uint.c ******************/
3789 /*
3790 ** 2020-04-14
3791 **
3792 ** The author disclaims copyright to this source code. In place of
@@ -5075,11 +5494,11 @@
5075 }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
5076 p->a[p->nUsed++] = y;
5077 }else if( p->bKeepSorted ){
5078 int i;
5079 i = percentBinarySearch(p, y, 0);
5080 if( i<p->nUsed ){
5081 memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
5082 }
5083 p->a[i] = y;
5084 p->nUsed++;
5085 }else{
@@ -5191,11 +5610,11 @@
5191
5192 /* Find and remove the row */
5193 i = percentBinarySearch(p, y, 1);
5194 if( i>=0 ){
5195 p->nUsed--;
5196 if( i<p->nUsed ){
5197 memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
5198 }
5199 }
5200 }
5201
@@ -5251,11 +5670,11 @@
5251 sqlite3 *db,
5252 char **pzErrMsg,
5253 const sqlite3_api_routines *pApi
5254 ){
5255 int rc = SQLITE_OK;
5256 int i;
5257 #if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE)
5258 (void)pApi; /* Unused parameter */
5259 #else
5260 SQLITE_EXTENSION_INIT2(pApi);
5261 #endif
@@ -16211,10 +16630,1000 @@
16211 }
16212 return rc;
16213 }
16214
16215 /************************* End ../ext/misc/stmtrand.c ********************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16216
16217 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
16218 #define SQLITE_SHELL_HAVE_RECOVER 1
16219 #else
16220 #define SQLITE_SHELL_HAVE_RECOVER 0
@@ -24511,10 +25920,11 @@
24511 }
24512
24513 #ifndef SQLITE_OMIT_LOAD_EXTENSION
24514 sqlite3_enable_load_extension(p->db, 1);
24515 #endif
 
24516 sqlite3_shathree_init(p->db, 0, 0);
24517 sqlite3_uint_init(p->db, 0, 0);
24518 sqlite3_stmtrand_init(p->db, 0, 0);
24519 sqlite3_decimal_init(p->db, 0, 0);
24520 sqlite3_percentile_init(p->db, 0, 0);
@@ -31374,13 +32784,11 @@
31374 " -table set output mode to 'table'\n"
31375 " -tabs set output mode to 'tabs'\n"
31376 " -unsafe-testing allow unsafe commands and modes for testing\n"
31377 " -version show SQLite version\n"
31378 " -vfs NAME use NAME as the default VFS\n"
31379 #ifdef SQLITE_ENABLE_VFSTRACE
31380 " -vfstrace enable tracing of all VFS calls\n"
31381 #endif
31382 #ifdef SQLITE_HAVE_ZLIB
31383 " -zip open the file as a ZIP Archive\n"
31384 #endif
31385 ;
31386 static void usage(int showDetail){
@@ -31502,10 +32910,11 @@
31502 int rc = 0;
31503 int warnInmemoryDb = 0;
31504 int readStdin = 1;
31505 int nCmd = 0;
31506 int nOptsEnd = argc;
 
31507 char **azCmd = 0;
31508 const char *zVfs = 0; /* Value of -vfs command-line option */
31509 #if !SQLITE_SHELL_IS_UTF8
31510 char **argvToFree = 0;
31511 int argcToFree = 0;
@@ -31696,21 +33105,13 @@
31696 switch( n ){
31697 case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break;
31698 case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break;
31699 default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break;
31700 }
31701 #ifdef SQLITE_ENABLE_VFSTRACE
31702 }else if( cli_strcmp(z,"-vfstrace")==0 ){
31703 extern int vfstrace_register(
31704 const char *zTraceName,
31705 const char *zOldVfsName,
31706 int (*xOut)(const char*,void*),
31707 void *pOutArg,
31708 int makeDefault
31709 );
31710 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
31711 #endif
31712 #ifdef SQLITE_ENABLE_MULTIPLEX
31713 }else if( cli_strcmp(z,"-multiplex")==0 ){
31714 extern int sqlite3_multiplex_initialize(const char*,int);
31715 sqlite3_multiplex_initialize(0, 1);
31716 #endif
@@ -31762,11 +33163,11 @@
31762 }else if( cli_strcmp(z,"-safe")==0 ){
31763 /* no-op - catch this on the second pass */
31764 }
31765 }
31766 #ifndef SQLITE_SHELL_FIDDLE
31767 verify_uninitialized();
31768 #endif
31769
31770
31771 #ifdef SQLITE_SHELL_INIT_PROC
31772 {
@@ -31951,14 +33352,12 @@
31951 }else if( cli_strcmp(z,"-sorterref")==0 ){
31952 i++;
31953 #endif
31954 }else if( cli_strcmp(z,"-vfs")==0 ){
31955 i++;
31956 #ifdef SQLITE_ENABLE_VFSTRACE
31957 }else if( cli_strcmp(z,"-vfstrace")==0 ){
31958 i++;
31959 #endif
31960 #ifdef SQLITE_ENABLE_MULTIPLEX
31961 }else if( cli_strcmp(z,"-multiplex")==0 ){
31962 i++;
31963 #endif
31964 }else if( cli_strcmp(z,"-help")==0 ){
@@ -32122,10 +33521,13 @@
32122 free(data.colWidth);
32123 free(data.zNonce);
32124 /* Clear the global data structure so that valgrind will detect memory
32125 ** leaks */
32126 memset(&data, 0, sizeof(data));
 
 
 
32127 #ifdef SQLITE_DEBUG
32128 if( sqlite3_memory_used()>mem_main_enter ){
32129 eputf("Memory leaked: %u bytes\n",
32130 (unsigned int)(sqlite3_memory_used()-mem_main_enter));
32131 }
32132
--- extsrc/shell.c
+++ extsrc/shell.c
@@ -1212,10 +1212,14 @@
1212 ++rv;
1213 }
1214 return rv;
1215 }
1216
1217 /* An fgets() equivalent, using Win32 file API for actual input.
1218 ** Input ends when given buffer is filled or a newline is read.
1219 ** If the FILE object is in text mode, swallows 0x0D. (ASCII CR)
1220 */
1221 SQLITE_INTERNAL_LINKAGE char *
1222 cfGets(char *cBuf, int n, FILE *pf){
1223 int nci = 0;
1224 struct FileAltIds fai = altIdsOfFile(pf);
1225 int fmode = _setmode(fai.fd, _O_BINARY);
@@ -1222,11 +1226,14 @@
1226 BOOL eatCR = (fmode & _O_TEXT)!=0;
1227 _setmode(fai.fd, fmode);
1228 while( nci < n-1 ){
1229 DWORD nr;
1230 if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
1231 if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){
1232 nci += nr;
1233 if( cBuf[nci-nr]=='\n' ) break;
1234 }
1235 }
1236 if( nci < n ) cBuf[nci] = 0;
1237 return (nci>0)? cBuf : 0;
1238 }
1239 # else
@@ -3783,10 +3790,422 @@
3790 }
3791 return rc;
3792 }
3793
3794 /************************* End ../ext/misc/shathree.c ********************/
3795 /************************* Begin ../ext/misc/sha1.c ******************/
3796 /*
3797 ** 2017-01-27
3798 **
3799 ** The author disclaims copyright to this source code. In place of
3800 ** a legal notice, here is a blessing:
3801 **
3802 ** May you do good and not evil.
3803 ** May you find forgiveness for yourself and forgive others.
3804 ** May you share freely, never taking more than you give.
3805 **
3806 ******************************************************************************
3807 **
3808 ** This SQLite extension implements functions that compute SHA1 hashes.
3809 ** Two SQL functions are implemented:
3810 **
3811 ** sha1(X)
3812 ** sha1_query(Y)
3813 **
3814 ** The sha1(X) function computes the SHA1 hash of the input X, or NULL if
3815 ** X is NULL.
3816 **
3817 ** The sha1_query(Y) function evalutes all queries in the SQL statements of Y
3818 ** and returns a hash of their results.
3819 */
3820 /* #include "sqlite3ext.h" */
3821 SQLITE_EXTENSION_INIT1
3822 #include <assert.h>
3823 #include <string.h>
3824 #include <stdarg.h>
3825
3826 /******************************************************************************
3827 ** The Hash Engine
3828 */
3829 /* Context for the SHA1 hash */
3830 typedef struct SHA1Context SHA1Context;
3831 struct SHA1Context {
3832 unsigned int state[5];
3833 unsigned int count[2];
3834 unsigned char buffer[64];
3835 };
3836
3837 #define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r))
3838 #define rol(x,k) SHA_ROT(x,k,32-(k))
3839 #define ror(x,k) SHA_ROT(x,32-(k),k)
3840
3841 #define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \
3842 |(rol(block[i],8)&0x00FF00FF))
3843 #define blk0be(i) block[i]
3844 #define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \
3845 ^block[(i+2)&15]^block[i&15],1))
3846
3847 /*
3848 * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
3849 *
3850 * Rl0() for little-endian and Rb0() for big-endian. Endianness is
3851 * determined at run-time.
3852 */
3853 #define Rl0(v,w,x,y,z,i) \
3854 z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2);
3855 #define Rb0(v,w,x,y,z,i) \
3856 z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2);
3857 #define R1(v,w,x,y,z,i) \
3858 z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2);
3859 #define R2(v,w,x,y,z,i) \
3860 z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2);
3861 #define R3(v,w,x,y,z,i) \
3862 z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2);
3863 #define R4(v,w,x,y,z,i) \
3864 z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2);
3865
3866 /*
3867 * Hash a single 512-bit block. This is the core of the algorithm.
3868 */
3869 static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){
3870 unsigned int qq[5]; /* a, b, c, d, e; */
3871 static int one = 1;
3872 unsigned int block[16];
3873 memcpy(block, buffer, 64);
3874 memcpy(qq,state,5*sizeof(unsigned int));
3875
3876 #define a qq[0]
3877 #define b qq[1]
3878 #define c qq[2]
3879 #define d qq[3]
3880 #define e qq[4]
3881
3882 /* Copy p->state[] to working vars */
3883 /*
3884 a = state[0];
3885 b = state[1];
3886 c = state[2];
3887 d = state[3];
3888 e = state[4];
3889 */
3890
3891 /* 4 rounds of 20 operations each. Loop unrolled. */
3892 if( 1 == *(unsigned char*)&one ){
3893 Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3);
3894 Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7);
3895 Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11);
3896 Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15);
3897 }else{
3898 Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3);
3899 Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7);
3900 Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11);
3901 Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15);
3902 }
3903 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
3904 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
3905 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
3906 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
3907 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
3908 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
3909 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
3910 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
3911 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
3912 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
3913 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
3914 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
3915 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
3916 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
3917 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
3918 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
3919
3920 /* Add the working vars back into context.state[] */
3921 state[0] += a;
3922 state[1] += b;
3923 state[2] += c;
3924 state[3] += d;
3925 state[4] += e;
3926
3927 #undef a
3928 #undef b
3929 #undef c
3930 #undef d
3931 #undef e
3932 }
3933
3934
3935 /* Initialize a SHA1 context */
3936 static void hash_init(SHA1Context *p){
3937 /* SHA1 initialization constants */
3938 p->state[0] = 0x67452301;
3939 p->state[1] = 0xEFCDAB89;
3940 p->state[2] = 0x98BADCFE;
3941 p->state[3] = 0x10325476;
3942 p->state[4] = 0xC3D2E1F0;
3943 p->count[0] = p->count[1] = 0;
3944 }
3945
3946 /* Add new content to the SHA1 hash */
3947 static void hash_step(
3948 SHA1Context *p, /* Add content to this context */
3949 const unsigned char *data, /* Data to be added */
3950 unsigned int len /* Number of bytes in data */
3951 ){
3952 unsigned int i, j;
3953
3954 j = p->count[0];
3955 if( (p->count[0] += len << 3) < j ){
3956 p->count[1] += (len>>29)+1;
3957 }
3958 j = (j >> 3) & 63;
3959 if( (j + len) > 63 ){
3960 (void)memcpy(&p->buffer[j], data, (i = 64-j));
3961 SHA1Transform(p->state, p->buffer);
3962 for(; i + 63 < len; i += 64){
3963 SHA1Transform(p->state, &data[i]);
3964 }
3965 j = 0;
3966 }else{
3967 i = 0;
3968 }
3969 (void)memcpy(&p->buffer[j], &data[i], len - i);
3970 }
3971
3972 /* Compute a string using sqlite3_vsnprintf() and hash it */
3973 static void hash_step_vformat(
3974 SHA1Context *p, /* Add content to this context */
3975 const char *zFormat,
3976 ...
3977 ){
3978 va_list ap;
3979 int n;
3980 char zBuf[50];
3981 va_start(ap, zFormat);
3982 sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
3983 va_end(ap);
3984 n = (int)strlen(zBuf);
3985 hash_step(p, (unsigned char*)zBuf, n);
3986 }
3987
3988
3989 /* Add padding and compute the message digest. Render the
3990 ** message digest as lower-case hexadecimal and put it into
3991 ** zOut[]. zOut[] must be at least 41 bytes long. */
3992 static void hash_finish(
3993 SHA1Context *p, /* The SHA1 context to finish and render */
3994 char *zOut, /* Store hex or binary hash here */
3995 int bAsBinary /* 1 for binary hash, 0 for hex hash */
3996 ){
3997 unsigned int i;
3998 unsigned char finalcount[8];
3999 unsigned char digest[20];
4000 static const char zEncode[] = "0123456789abcdef";
4001
4002 for (i = 0; i < 8; i++){
4003 finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)]
4004 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
4005 }
4006 hash_step(p, (const unsigned char *)"\200", 1);
4007 while ((p->count[0] & 504) != 448){
4008 hash_step(p, (const unsigned char *)"\0", 1);
4009 }
4010 hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */
4011 for (i = 0; i < 20; i++){
4012 digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
4013 }
4014 if( bAsBinary ){
4015 memcpy(zOut, digest, 20);
4016 }else{
4017 for(i=0; i<20; i++){
4018 zOut[i*2] = zEncode[(digest[i]>>4)&0xf];
4019 zOut[i*2+1] = zEncode[digest[i] & 0xf];
4020 }
4021 zOut[i*2]= 0;
4022 }
4023 }
4024 /* End of the hashing logic
4025 *****************************************************************************/
4026
4027 /*
4028 ** Implementation of the sha1(X) function.
4029 **
4030 ** Return a lower-case hexadecimal rendering of the SHA1 hash of the
4031 ** argument X. If X is a BLOB, it is hashed as is. For all other
4032 ** types of input, X is converted into a UTF-8 string and the string
4033 ** is hash without the trailing 0x00 terminator. The hash of a NULL
4034 ** value is NULL.
4035 */
4036 static void sha1Func(
4037 sqlite3_context *context,
4038 int argc,
4039 sqlite3_value **argv
4040 ){
4041 SHA1Context cx;
4042 int eType = sqlite3_value_type(argv[0]);
4043 int nByte = sqlite3_value_bytes(argv[0]);
4044 char zOut[44];
4045
4046 assert( argc==1 );
4047 if( eType==SQLITE_NULL ) return;
4048 hash_init(&cx);
4049 if( eType==SQLITE_BLOB ){
4050 hash_step(&cx, sqlite3_value_blob(argv[0]), nByte);
4051 }else{
4052 hash_step(&cx, sqlite3_value_text(argv[0]), nByte);
4053 }
4054 if( sqlite3_user_data(context)!=0 ){
4055 hash_finish(&cx, zOut, 1);
4056 sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT);
4057 }else{
4058 hash_finish(&cx, zOut, 0);
4059 sqlite3_result_blob(context, zOut, 40, SQLITE_TRANSIENT);
4060 }
4061 }
4062
4063 /*
4064 ** Implementation of the sha1_query(SQL) function.
4065 **
4066 ** This function compiles and runs the SQL statement(s) given in the
4067 ** argument. The results are hashed using SHA1 and that hash is returned.
4068 **
4069 ** The original SQL text is included as part of the hash.
4070 **
4071 ** The hash is not just a concatenation of the outputs. Each query
4072 ** is delimited and each row and value within the query is delimited,
4073 ** with all values being marked with their datatypes.
4074 */
4075 static void sha1QueryFunc(
4076 sqlite3_context *context,
4077 int argc,
4078 sqlite3_value **argv
4079 ){
4080 sqlite3 *db = sqlite3_context_db_handle(context);
4081 const char *zSql = (const char*)sqlite3_value_text(argv[0]);
4082 sqlite3_stmt *pStmt = 0;
4083 int nCol; /* Number of columns in the result set */
4084 int i; /* Loop counter */
4085 int rc;
4086 int n;
4087 const char *z;
4088 SHA1Context cx;
4089 char zOut[44];
4090
4091 assert( argc==1 );
4092 if( zSql==0 ) return;
4093 hash_init(&cx);
4094 while( zSql[0] ){
4095 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
4096 if( rc ){
4097 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
4098 zSql, sqlite3_errmsg(db));
4099 sqlite3_finalize(pStmt);
4100 sqlite3_result_error(context, zMsg, -1);
4101 sqlite3_free(zMsg);
4102 return;
4103 }
4104 if( !sqlite3_stmt_readonly(pStmt) ){
4105 char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
4106 sqlite3_finalize(pStmt);
4107 sqlite3_result_error(context, zMsg, -1);
4108 sqlite3_free(zMsg);
4109 return;
4110 }
4111 nCol = sqlite3_column_count(pStmt);
4112 z = sqlite3_sql(pStmt);
4113 n = (int)strlen(z);
4114 hash_step_vformat(&cx,"S%d:",n);
4115 hash_step(&cx,(unsigned char*)z,n);
4116
4117 /* Compute a hash over the result of the query */
4118 while( SQLITE_ROW==sqlite3_step(pStmt) ){
4119 hash_step(&cx,(const unsigned char*)"R",1);
4120 for(i=0; i<nCol; i++){
4121 switch( sqlite3_column_type(pStmt,i) ){
4122 case SQLITE_NULL: {
4123 hash_step(&cx, (const unsigned char*)"N",1);
4124 break;
4125 }
4126 case SQLITE_INTEGER: {
4127 sqlite3_uint64 u;
4128 int j;
4129 unsigned char x[9];
4130 sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
4131 memcpy(&u, &v, 8);
4132 for(j=8; j>=1; j--){
4133 x[j] = u & 0xff;
4134 u >>= 8;
4135 }
4136 x[0] = 'I';
4137 hash_step(&cx, x, 9);
4138 break;
4139 }
4140 case SQLITE_FLOAT: {
4141 sqlite3_uint64 u;
4142 int j;
4143 unsigned char x[9];
4144 double r = sqlite3_column_double(pStmt,i);
4145 memcpy(&u, &r, 8);
4146 for(j=8; j>=1; j--){
4147 x[j] = u & 0xff;
4148 u >>= 8;
4149 }
4150 x[0] = 'F';
4151 hash_step(&cx,x,9);
4152 break;
4153 }
4154 case SQLITE_TEXT: {
4155 int n2 = sqlite3_column_bytes(pStmt, i);
4156 const unsigned char *z2 = sqlite3_column_text(pStmt, i);
4157 hash_step_vformat(&cx,"T%d:",n2);
4158 hash_step(&cx, z2, n2);
4159 break;
4160 }
4161 case SQLITE_BLOB: {
4162 int n2 = sqlite3_column_bytes(pStmt, i);
4163 const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
4164 hash_step_vformat(&cx,"B%d:",n2);
4165 hash_step(&cx, z2, n2);
4166 break;
4167 }
4168 }
4169 }
4170 }
4171 sqlite3_finalize(pStmt);
4172 }
4173 hash_finish(&cx, zOut, 0);
4174 sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT);
4175 }
4176
4177
4178 #ifdef _WIN32
4179
4180 #endif
4181 int sqlite3_sha_init(
4182 sqlite3 *db,
4183 char **pzErrMsg,
4184 const sqlite3_api_routines *pApi
4185 ){
4186 int rc = SQLITE_OK;
4187 static int one = 1;
4188 SQLITE_EXTENSION_INIT2(pApi);
4189 (void)pzErrMsg; /* Unused parameter */
4190 rc = sqlite3_create_function(db, "sha1", 1,
4191 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
4192 0, sha1Func, 0, 0);
4193 if( rc==SQLITE_OK ){
4194 rc = sqlite3_create_function(db, "sha1b", 1,
4195 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
4196 (void*)&one, sha1Func, 0, 0);
4197 }
4198 if( rc==SQLITE_OK ){
4199 rc = sqlite3_create_function(db, "sha1_query", 1,
4200 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
4201 sha1QueryFunc, 0, 0);
4202 }
4203 return rc;
4204 }
4205
4206 /************************* End ../ext/misc/sha1.c ********************/
4207 /************************* Begin ../ext/misc/uint.c ******************/
4208 /*
4209 ** 2020-04-14
4210 **
4211 ** The author disclaims copyright to this source code. In place of
@@ -5075,11 +5494,11 @@
5494 }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
5495 p->a[p->nUsed++] = y;
5496 }else if( p->bKeepSorted ){
5497 int i;
5498 i = percentBinarySearch(p, y, 0);
5499 if( i<(int)p->nUsed ){
5500 memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
5501 }
5502 p->a[i] = y;
5503 p->nUsed++;
5504 }else{
@@ -5191,11 +5610,11 @@
5610
5611 /* Find and remove the row */
5612 i = percentBinarySearch(p, y, 1);
5613 if( i>=0 ){
5614 p->nUsed--;
5615 if( i<(int)p->nUsed ){
5616 memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
5617 }
5618 }
5619 }
5620
@@ -5251,11 +5670,11 @@
5670 sqlite3 *db,
5671 char **pzErrMsg,
5672 const sqlite3_api_routines *pApi
5673 ){
5674 int rc = SQLITE_OK;
5675 unsigned int i;
5676 #if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE)
5677 (void)pApi; /* Unused parameter */
5678 #else
5679 SQLITE_EXTENSION_INIT2(pApi);
5680 #endif
@@ -16211,10 +16630,1000 @@
16630 }
16631 return rc;
16632 }
16633
16634 /************************* End ../ext/misc/stmtrand.c ********************/
16635 /************************* Begin ../ext/misc/vfstrace.c ******************/
16636 /*
16637 ** 2011 March 16
16638 **
16639 ** The author disclaims copyright to this source code. In place of
16640 ** a legal notice, here is a blessing:
16641 **
16642 ** May you do good and not evil.
16643 ** May you find forgiveness for yourself and forgive others.
16644 ** May you share freely, never taking more than you give.
16645 **
16646 ******************************************************************************
16647 **
16648 ** This file contains code implements a VFS shim that writes diagnostic
16649 ** output for each VFS call, similar to "strace".
16650 **
16651 ** USAGE:
16652 **
16653 ** This source file exports a single symbol which is the name of a
16654 ** function:
16655 **
16656 ** int vfstrace_register(
16657 ** const char *zTraceName, // Name of the newly constructed VFS
16658 ** const char *zOldVfsName, // Name of the underlying VFS
16659 ** int (*xOut)(const char*,void*), // Output routine. ex: fputs
16660 ** void *pOutArg, // 2nd argument to xOut. ex: stderr
16661 ** int makeDefault // Make the new VFS the default
16662 ** );
16663 **
16664 ** Applications that want to trace their VFS usage must provide a callback
16665 ** function with this prototype:
16666 **
16667 ** int traceOutput(const char *zMessage, void *pAppData);
16668 **
16669 ** This function will "output" the trace messages, where "output" can
16670 ** mean different things to different applications. The traceOutput function
16671 ** for the command-line shell (see shell.c) is "fputs" from the standard
16672 ** library, which means that all trace output is written on the stream
16673 ** specified by the second argument. In the case of the command-line shell
16674 ** the second argument is stderr. Other applications might choose to output
16675 ** trace information to a file, over a socket, or write it into a buffer.
16676 **
16677 ** The vfstrace_register() function creates a new "shim" VFS named by
16678 ** the zTraceName parameter. A "shim" VFS is an SQLite backend that does
16679 ** not really perform the duties of a true backend, but simply filters or
16680 ** interprets VFS calls before passing them off to another VFS which does
16681 ** the actual work. In this case the other VFS - the one that does the
16682 ** real work - is identified by the second parameter, zOldVfsName. If
16683 ** the 2nd parameter is NULL then the default VFS is used. The common
16684 ** case is for the 2nd parameter to be NULL.
16685 **
16686 ** The third and fourth parameters are the pointer to the output function
16687 ** and the second argument to the output function. For the SQLite
16688 ** command-line shell, when the -vfstrace option is used, these parameters
16689 ** are fputs and stderr, respectively.
16690 **
16691 ** The fifth argument is true (non-zero) to cause the newly created VFS
16692 ** to become the default VFS. The common case is for the fifth parameter
16693 ** to be true.
16694 **
16695 ** The call to vfstrace_register() simply creates the shim VFS that does
16696 ** tracing. The application must also arrange to use the new VFS for
16697 ** all database connections that are created and for which tracing is
16698 ** desired. This can be done by specifying the trace VFS using URI filename
16699 ** notation, or by specifying the trace VFS as the 4th parameter to
16700 ** sqlite3_open_v2() or by making the trace VFS be the default (by setting
16701 ** the 5th parameter of vfstrace_register() to 1).
16702 **
16703 **
16704 ** ENABLING VFSTRACE IN A COMMAND-LINE SHELL
16705 **
16706 ** The SQLite command line shell implemented by the shell.c source file
16707 ** can be used with this module. To compile in -vfstrace support, first
16708 ** gather this file (test_vfstrace.c), the shell source file (shell.c),
16709 ** and the SQLite amalgamation source files (sqlite3.c, sqlite3.h) into
16710 ** the working directory. Then compile using a command like the following:
16711 **
16712 ** gcc -o sqlite3 -Os -I. -DSQLITE_ENABLE_VFSTRACE \
16713 ** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \
16714 ** -DHAVE_READLINE -DHAVE_USLEEP=1 \
16715 ** shell.c test_vfstrace.c sqlite3.c -ldl -lreadline -lncurses
16716 **
16717 ** The gcc command above works on Linux and provides (in addition to the
16718 ** -vfstrace option) support for FTS3 and FTS4, RTREE, and command-line
16719 ** editing using the readline library. The command-line shell does not
16720 ** use threads so we added -DSQLITE_THREADSAFE=0 just to make the code
16721 ** run a little faster. For compiling on a Mac, you'll probably need
16722 ** to omit the -DHAVE_READLINE, the -lreadline, and the -lncurses options.
16723 ** The compilation could be simplified to just this:
16724 **
16725 ** gcc -DSQLITE_ENABLE_VFSTRACE \
16726 ** shell.c test_vfstrace.c sqlite3.c -ldl -lpthread
16727 **
16728 ** In this second example, all unnecessary options have been removed
16729 ** Note that since the code is now threadsafe, we had to add the -lpthread
16730 ** option to pull in the pthreads library.
16731 **
16732 ** To cross-compile for windows using MinGW, a command like this might
16733 ** work:
16734 **
16735 ** /opt/mingw/bin/i386-mingw32msvc-gcc -o sqlite3.exe -Os -I \
16736 ** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_VFSTRACE \
16737 ** shell.c test_vfstrace.c sqlite3.c
16738 **
16739 ** Similar compiler commands will work on different systems. The key
16740 ** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that
16741 ** the shell.c source file will know to include the -vfstrace command-line
16742 ** option and (2) you must compile and link the three source files
16743 ** shell,c, test_vfstrace.c, and sqlite3.c.
16744 */
16745 #include <stdlib.h>
16746 #include <string.h>
16747 /* #include "sqlite3.h" */
16748
16749 /*
16750 ** An instance of this structure is attached to the each trace VFS to
16751 ** provide auxiliary information.
16752 */
16753 typedef struct vfstrace_info vfstrace_info;
16754 struct vfstrace_info {
16755 sqlite3_vfs *pRootVfs; /* The underlying real VFS */
16756 int (*xOut)(const char*, void*); /* Send output here */
16757 void *pOutArg; /* First argument to xOut */
16758 const char *zVfsName; /* Name of this trace-VFS */
16759 sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */
16760 };
16761
16762 /*
16763 ** The sqlite3_file object for the trace VFS
16764 */
16765 typedef struct vfstrace_file vfstrace_file;
16766 struct vfstrace_file {
16767 sqlite3_file base; /* Base class. Must be first */
16768 vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */
16769 const char *zFName; /* Base name of the file */
16770 sqlite3_file *pReal; /* The real underlying file */
16771 };
16772
16773 /*
16774 ** Method declarations for vfstrace_file.
16775 */
16776 static int vfstraceClose(sqlite3_file*);
16777 static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
16778 static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64);
16779 static int vfstraceTruncate(sqlite3_file*, sqlite3_int64 size);
16780 static int vfstraceSync(sqlite3_file*, int flags);
16781 static int vfstraceFileSize(sqlite3_file*, sqlite3_int64 *pSize);
16782 static int vfstraceLock(sqlite3_file*, int);
16783 static int vfstraceUnlock(sqlite3_file*, int);
16784 static int vfstraceCheckReservedLock(sqlite3_file*, int *);
16785 static int vfstraceFileControl(sqlite3_file*, int op, void *pArg);
16786 static int vfstraceSectorSize(sqlite3_file*);
16787 static int vfstraceDeviceCharacteristics(sqlite3_file*);
16788 static int vfstraceShmLock(sqlite3_file*,int,int,int);
16789 static int vfstraceShmMap(sqlite3_file*,int,int,int, void volatile **);
16790 static void vfstraceShmBarrier(sqlite3_file*);
16791 static int vfstraceShmUnmap(sqlite3_file*,int);
16792
16793 /*
16794 ** Method declarations for vfstrace_vfs.
16795 */
16796 static int vfstraceOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
16797 static int vfstraceDelete(sqlite3_vfs*, const char *zName, int syncDir);
16798 static int vfstraceAccess(sqlite3_vfs*, const char *zName, int flags, int *);
16799 static int vfstraceFullPathname(sqlite3_vfs*, const char *zName, int, char *);
16800 static void *vfstraceDlOpen(sqlite3_vfs*, const char *zFilename);
16801 static void vfstraceDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
16802 static void (*vfstraceDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
16803 static void vfstraceDlClose(sqlite3_vfs*, void*);
16804 static int vfstraceRandomness(sqlite3_vfs*, int nByte, char *zOut);
16805 static int vfstraceSleep(sqlite3_vfs*, int microseconds);
16806 static int vfstraceCurrentTime(sqlite3_vfs*, double*);
16807 static int vfstraceGetLastError(sqlite3_vfs*, int, char*);
16808 static int vfstraceCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
16809 static int vfstraceSetSystemCall(sqlite3_vfs*,const char*, sqlite3_syscall_ptr);
16810 static sqlite3_syscall_ptr vfstraceGetSystemCall(sqlite3_vfs*, const char *);
16811 static const char *vfstraceNextSystemCall(sqlite3_vfs*, const char *zName);
16812
16813 /*
16814 ** Return a pointer to the tail of the pathname. Examples:
16815 **
16816 ** /home/drh/xyzzy.txt -> xyzzy.txt
16817 ** xyzzy.txt -> xyzzy.txt
16818 */
16819 static const char *fileTail(const char *z){
16820 size_t i;
16821 if( z==0 ) return 0;
16822 i = strlen(z)-1;
16823 while( i>0 && z[i-1]!='/' ){ i--; }
16824 return &z[i];
16825 }
16826
16827 /*
16828 ** Send trace output defined by zFormat and subsequent arguments.
16829 */
16830 static void vfstrace_printf(
16831 vfstrace_info *pInfo,
16832 const char *zFormat,
16833 ...
16834 ){
16835 va_list ap;
16836 char *zMsg;
16837 va_start(ap, zFormat);
16838 zMsg = sqlite3_vmprintf(zFormat, ap);
16839 va_end(ap);
16840 pInfo->xOut(zMsg, pInfo->pOutArg);
16841 sqlite3_free(zMsg);
16842 }
16843
16844 /*
16845 ** Try to convert an error code into a symbolic name for that error code.
16846 */
16847 static const char *vfstrace_errcode_name(int rc ){
16848 const char *zVal = 0;
16849 switch( rc ){
16850 case SQLITE_OK: zVal = "SQLITE_OK"; break;
16851 case SQLITE_INTERNAL: zVal = "SQLITE_INTERNAL"; break;
16852 case SQLITE_ERROR: zVal = "SQLITE_ERROR"; break;
16853 case SQLITE_PERM: zVal = "SQLITE_PERM"; break;
16854 case SQLITE_ABORT: zVal = "SQLITE_ABORT"; break;
16855 case SQLITE_BUSY: zVal = "SQLITE_BUSY"; break;
16856 case SQLITE_LOCKED: zVal = "SQLITE_LOCKED"; break;
16857 case SQLITE_NOMEM: zVal = "SQLITE_NOMEM"; break;
16858 case SQLITE_READONLY: zVal = "SQLITE_READONLY"; break;
16859 case SQLITE_INTERRUPT: zVal = "SQLITE_INTERRUPT"; break;
16860 case SQLITE_IOERR: zVal = "SQLITE_IOERR"; break;
16861 case SQLITE_CORRUPT: zVal = "SQLITE_CORRUPT"; break;
16862 case SQLITE_NOTFOUND: zVal = "SQLITE_NOTFOUND"; break;
16863 case SQLITE_FULL: zVal = "SQLITE_FULL"; break;
16864 case SQLITE_CANTOPEN: zVal = "SQLITE_CANTOPEN"; break;
16865 case SQLITE_PROTOCOL: zVal = "SQLITE_PROTOCOL"; break;
16866 case SQLITE_EMPTY: zVal = "SQLITE_EMPTY"; break;
16867 case SQLITE_SCHEMA: zVal = "SQLITE_SCHEMA"; break;
16868 case SQLITE_TOOBIG: zVal = "SQLITE_TOOBIG"; break;
16869 case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT"; break;
16870 case SQLITE_MISMATCH: zVal = "SQLITE_MISMATCH"; break;
16871 case SQLITE_MISUSE: zVal = "SQLITE_MISUSE"; break;
16872 case SQLITE_NOLFS: zVal = "SQLITE_NOLFS"; break;
16873 case SQLITE_IOERR_READ: zVal = "SQLITE_IOERR_READ"; break;
16874 case SQLITE_IOERR_SHORT_READ: zVal = "SQLITE_IOERR_SHORT_READ"; break;
16875 case SQLITE_IOERR_WRITE: zVal = "SQLITE_IOERR_WRITE"; break;
16876 case SQLITE_IOERR_FSYNC: zVal = "SQLITE_IOERR_FSYNC"; break;
16877 case SQLITE_IOERR_DIR_FSYNC: zVal = "SQLITE_IOERR_DIR_FSYNC"; break;
16878 case SQLITE_IOERR_TRUNCATE: zVal = "SQLITE_IOERR_TRUNCATE"; break;
16879 case SQLITE_IOERR_FSTAT: zVal = "SQLITE_IOERR_FSTAT"; break;
16880 case SQLITE_IOERR_UNLOCK: zVal = "SQLITE_IOERR_UNLOCK"; break;
16881 case SQLITE_IOERR_RDLOCK: zVal = "SQLITE_IOERR_RDLOCK"; break;
16882 case SQLITE_IOERR_DELETE: zVal = "SQLITE_IOERR_DELETE"; break;
16883 case SQLITE_IOERR_BLOCKED: zVal = "SQLITE_IOERR_BLOCKED"; break;
16884 case SQLITE_IOERR_NOMEM: zVal = "SQLITE_IOERR_NOMEM"; break;
16885 case SQLITE_IOERR_ACCESS: zVal = "SQLITE_IOERR_ACCESS"; break;
16886 case SQLITE_IOERR_CHECKRESERVEDLOCK:
16887 zVal = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break;
16888 case SQLITE_IOERR_LOCK: zVal = "SQLITE_IOERR_LOCK"; break;
16889 case SQLITE_IOERR_CLOSE: zVal = "SQLITE_IOERR_CLOSE"; break;
16890 case SQLITE_IOERR_DIR_CLOSE: zVal = "SQLITE_IOERR_DIR_CLOSE"; break;
16891 case SQLITE_IOERR_SHMOPEN: zVal = "SQLITE_IOERR_SHMOPEN"; break;
16892 case SQLITE_IOERR_SHMSIZE: zVal = "SQLITE_IOERR_SHMSIZE"; break;
16893 case SQLITE_IOERR_SHMLOCK: zVal = "SQLITE_IOERR_SHMLOCK"; break;
16894 case SQLITE_IOERR_SHMMAP: zVal = "SQLITE_IOERR_SHMMAP"; break;
16895 case SQLITE_IOERR_SEEK: zVal = "SQLITE_IOERR_SEEK"; break;
16896 case SQLITE_IOERR_GETTEMPPATH: zVal = "SQLITE_IOERR_GETTEMPPATH"; break;
16897 case SQLITE_IOERR_CONVPATH: zVal = "SQLITE_IOERR_CONVPATH"; break;
16898 case SQLITE_READONLY_DBMOVED: zVal = "SQLITE_READONLY_DBMOVED"; break;
16899 case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break;
16900 case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break;
16901 case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break;
16902 }
16903 return zVal;
16904 }
16905
16906 /*
16907 ** Convert value rc into a string and print it using zFormat. zFormat
16908 ** should have exactly one %s
16909 */
16910 static void vfstrace_print_errcode(
16911 vfstrace_info *pInfo,
16912 const char *zFormat,
16913 int rc
16914 ){
16915 const char *zVal;
16916 char zBuf[50];
16917 zVal = vfstrace_errcode_name(rc);
16918 if( zVal==0 ){
16919 zVal = vfstrace_errcode_name(rc&0xff);
16920 if( zVal ){
16921 sqlite3_snprintf(sizeof(zBuf), zBuf, "%s | 0x%x", zVal, rc&0xffff00);
16922 }else{
16923 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d (0x%x)", rc, rc);
16924 }
16925 zVal = zBuf;
16926 }
16927 vfstrace_printf(pInfo, zFormat, zVal);
16928 }
16929
16930 /*
16931 ** Append to a buffer.
16932 */
16933 static void strappend(char *z, int *pI, const char *zAppend){
16934 int i = *pI;
16935 while( zAppend[0] ){ z[i++] = *(zAppend++); }
16936 z[i] = 0;
16937 *pI = i;
16938 }
16939
16940 /*
16941 ** Close an vfstrace-file.
16942 */
16943 static int vfstraceClose(sqlite3_file *pFile){
16944 vfstrace_file *p = (vfstrace_file *)pFile;
16945 vfstrace_info *pInfo = p->pInfo;
16946 int rc;
16947 vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName);
16948 rc = p->pReal->pMethods->xClose(p->pReal);
16949 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16950 if( rc==SQLITE_OK ){
16951 sqlite3_free((void*)p->base.pMethods);
16952 p->base.pMethods = 0;
16953 }
16954 return rc;
16955 }
16956
16957 /*
16958 ** Read data from an vfstrace-file.
16959 */
16960 static int vfstraceRead(
16961 sqlite3_file *pFile,
16962 void *zBuf,
16963 int iAmt,
16964 sqlite_int64 iOfst
16965 ){
16966 vfstrace_file *p = (vfstrace_file *)pFile;
16967 vfstrace_info *pInfo = p->pInfo;
16968 int rc;
16969 vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)",
16970 pInfo->zVfsName, p->zFName, iAmt, iOfst);
16971 rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
16972 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16973 return rc;
16974 }
16975
16976 /*
16977 ** Write data to an vfstrace-file.
16978 */
16979 static int vfstraceWrite(
16980 sqlite3_file *pFile,
16981 const void *zBuf,
16982 int iAmt,
16983 sqlite_int64 iOfst
16984 ){
16985 vfstrace_file *p = (vfstrace_file *)pFile;
16986 vfstrace_info *pInfo = p->pInfo;
16987 int rc;
16988 vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)",
16989 pInfo->zVfsName, p->zFName, iAmt, iOfst);
16990 rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
16991 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
16992 return rc;
16993 }
16994
16995 /*
16996 ** Truncate an vfstrace-file.
16997 */
16998 static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){
16999 vfstrace_file *p = (vfstrace_file *)pFile;
17000 vfstrace_info *pInfo = p->pInfo;
17001 int rc;
17002 vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName,
17003 size);
17004 rc = p->pReal->pMethods->xTruncate(p->pReal, size);
17005 vfstrace_printf(pInfo, " -> %d\n", rc);
17006 return rc;
17007 }
17008
17009 /*
17010 ** Sync an vfstrace-file.
17011 */
17012 static int vfstraceSync(sqlite3_file *pFile, int flags){
17013 vfstrace_file *p = (vfstrace_file *)pFile;
17014 vfstrace_info *pInfo = p->pInfo;
17015 int rc;
17016 int i;
17017 char zBuf[100];
17018 memcpy(zBuf, "|0", 3);
17019 i = 0;
17020 if( flags & SQLITE_SYNC_FULL ) strappend(zBuf, &i, "|FULL");
17021 else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL");
17022 if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY");
17023 if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
17024 sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
17025 }
17026 vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
17027 &zBuf[1]);
17028 rc = p->pReal->pMethods->xSync(p->pReal, flags);
17029 vfstrace_printf(pInfo, " -> %d\n", rc);
17030 return rc;
17031 }
17032
17033 /*
17034 ** Return the current file-size of an vfstrace-file.
17035 */
17036 static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
17037 vfstrace_file *p = (vfstrace_file *)pFile;
17038 vfstrace_info *pInfo = p->pInfo;
17039 int rc;
17040 vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName);
17041 rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
17042 vfstrace_print_errcode(pInfo, " -> %s,", rc);
17043 vfstrace_printf(pInfo, " size=%lld\n", *pSize);
17044 return rc;
17045 }
17046
17047 /*
17048 ** Return the name of a lock.
17049 */
17050 static const char *lockName(int eLock){
17051 const char *azLockNames[] = {
17052 "NONE", "SHARED", "RESERVED", "PENDING", "EXCLUSIVE"
17053 };
17054 if( eLock<0 || eLock>=sizeof(azLockNames)/sizeof(azLockNames[0]) ){
17055 return "???";
17056 }else{
17057 return azLockNames[eLock];
17058 }
17059 }
17060
17061 /*
17062 ** Lock an vfstrace-file.
17063 */
17064 static int vfstraceLock(sqlite3_file *pFile, int eLock){
17065 vfstrace_file *p = (vfstrace_file *)pFile;
17066 vfstrace_info *pInfo = p->pInfo;
17067 int rc;
17068 vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName,
17069 lockName(eLock));
17070 rc = p->pReal->pMethods->xLock(p->pReal, eLock);
17071 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17072 return rc;
17073 }
17074
17075 /*
17076 ** Unlock an vfstrace-file.
17077 */
17078 static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
17079 vfstrace_file *p = (vfstrace_file *)pFile;
17080 vfstrace_info *pInfo = p->pInfo;
17081 int rc;
17082 vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
17083 lockName(eLock));
17084 rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
17085 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17086 return rc;
17087 }
17088
17089 /*
17090 ** Check if another file-handle holds a RESERVED lock on an vfstrace-file.
17091 */
17092 static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){
17093 vfstrace_file *p = (vfstrace_file *)pFile;
17094 vfstrace_info *pInfo = p->pInfo;
17095 int rc;
17096 vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)",
17097 pInfo->zVfsName, p->zFName);
17098 rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
17099 vfstrace_print_errcode(pInfo, " -> %s", rc);
17100 vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
17101 return rc;
17102 }
17103
17104 /*
17105 ** File control method. For custom operations on an vfstrace-file.
17106 */
17107 static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
17108 vfstrace_file *p = (vfstrace_file *)pFile;
17109 vfstrace_info *pInfo = p->pInfo;
17110 int rc;
17111 char zBuf[100];
17112 char zBuf2[100];
17113 char *zOp;
17114 char *zRVal = 0;
17115 switch( op ){
17116 case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
17117 case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
17118 case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break;
17119 case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break;
17120 case SQLITE_FCNTL_SIZE_HINT: {
17121 sqlite3_snprintf(sizeof(zBuf), zBuf, "SIZE_HINT,%lld",
17122 *(sqlite3_int64*)pArg);
17123 zOp = zBuf;
17124 break;
17125 }
17126 case SQLITE_FCNTL_CHUNK_SIZE: {
17127 sqlite3_snprintf(sizeof(zBuf), zBuf, "CHUNK_SIZE,%d", *(int*)pArg);
17128 zOp = zBuf;
17129 break;
17130 }
17131 case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break;
17132 case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break;
17133 case SQLITE_FCNTL_PERSIST_WAL: {
17134 sqlite3_snprintf(sizeof(zBuf), zBuf, "PERSIST_WAL,%d", *(int*)pArg);
17135 zOp = zBuf;
17136 break;
17137 }
17138 case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break;
17139 case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break;
17140 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
17141 case SQLITE_FCNTL_PRAGMA: {
17142 const char *const* a = (const char*const*)pArg;
17143 sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
17144 zOp = zBuf;
17145 break;
17146 }
17147 case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break;
17148 case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break;
17149 case SQLITE_FCNTL_MMAP_SIZE: {
17150 sqlite3_int64 iMMap = *(sqlite3_int64*)pArg;
17151 sqlite3_snprintf(sizeof(zBuf), zBuf, "MMAP_SIZE,%lld",iMMap);
17152 zOp = zBuf;
17153 break;
17154 }
17155 case SQLITE_FCNTL_TRACE: zOp = "TRACE"; break;
17156 case SQLITE_FCNTL_HAS_MOVED: zOp = "HAS_MOVED"; break;
17157 case SQLITE_FCNTL_SYNC: zOp = "SYNC"; break;
17158 case SQLITE_FCNTL_COMMIT_PHASETWO: zOp = "COMMIT_PHASETWO"; break;
17159 case SQLITE_FCNTL_WIN32_SET_HANDLE: zOp = "WIN32_SET_HANDLE"; break;
17160 case SQLITE_FCNTL_WAL_BLOCK: zOp = "WAL_BLOCK"; break;
17161 case SQLITE_FCNTL_ZIPVFS: zOp = "ZIPVFS"; break;
17162 case SQLITE_FCNTL_RBU: zOp = "RBU"; break;
17163 case SQLITE_FCNTL_VFS_POINTER: zOp = "VFS_POINTER"; break;
17164 case SQLITE_FCNTL_JOURNAL_POINTER: zOp = "JOURNAL_POINTER"; break;
17165 case SQLITE_FCNTL_WIN32_GET_HANDLE: zOp = "WIN32_GET_HANDLE"; break;
17166 case SQLITE_FCNTL_PDB: zOp = "PDB"; break;
17167 case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: zOp = "BEGIN_ATOMIC_WRITE"; break;
17168 case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: zOp = "COMMIT_ATOMIC_WRITE"; break;
17169 case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
17170 zOp = "ROLLBACK_ATOMIC_WRITE";
17171 break;
17172 }
17173 case SQLITE_FCNTL_LOCK_TIMEOUT: {
17174 sqlite3_snprintf(sizeof(zBuf), zBuf, "LOCK_TIMEOUT,%d", *(int*)pArg);
17175 zOp = zBuf;
17176 break;
17177 }
17178 case SQLITE_FCNTL_DATA_VERSION: zOp = "DATA_VERSION"; break;
17179 case SQLITE_FCNTL_SIZE_LIMIT: zOp = "SIZE_LIMIT"; break;
17180 case SQLITE_FCNTL_CKPT_DONE: zOp = "CKPT_DONE"; break;
17181 case SQLITE_FCNTL_RESERVE_BYTES: zOp = "RESERVED_BYTES"; break;
17182 case SQLITE_FCNTL_CKPT_START: zOp = "CKPT_START"; break;
17183 case SQLITE_FCNTL_EXTERNAL_READER: zOp = "EXTERNAL_READER"; break;
17184 case SQLITE_FCNTL_CKSM_FILE: zOp = "CKSM_FILE"; break;
17185 case SQLITE_FCNTL_RESET_CACHE: zOp = "RESET_CACHE"; break;
17186 case 0xca093fa0: zOp = "DB_UNCHANGED"; break;
17187 default: {
17188 sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op);
17189 zOp = zBuf;
17190 break;
17191 }
17192 }
17193 vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)",
17194 pInfo->zVfsName, p->zFName, zOp);
17195 rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
17196 if( rc==SQLITE_OK ){
17197 switch( op ){
17198 case SQLITE_FCNTL_VFSNAME: {
17199 *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
17200 pInfo->zVfsName, *(char**)pArg);
17201 zRVal = *(char**)pArg;
17202 break;
17203 }
17204 case SQLITE_FCNTL_MMAP_SIZE: {
17205 sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%lld", *(sqlite3_int64*)pArg);
17206 zRVal = zBuf2;
17207 break;
17208 }
17209 case SQLITE_FCNTL_HAS_MOVED:
17210 case SQLITE_FCNTL_PERSIST_WAL: {
17211 sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%d", *(int*)pArg);
17212 zRVal = zBuf2;
17213 break;
17214 }
17215 case SQLITE_FCNTL_PRAGMA:
17216 case SQLITE_FCNTL_TEMPFILENAME: {
17217 zRVal = *(char**)pArg;
17218 break;
17219 }
17220 }
17221 }
17222 if( zRVal ){
17223 vfstrace_print_errcode(pInfo, " -> %s", rc);
17224 vfstrace_printf(pInfo, ", %s\n", zRVal);
17225 }else{
17226 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17227 }
17228 return rc;
17229 }
17230
17231 /*
17232 ** Return the sector-size in bytes for an vfstrace-file.
17233 */
17234 static int vfstraceSectorSize(sqlite3_file *pFile){
17235 vfstrace_file *p = (vfstrace_file *)pFile;
17236 vfstrace_info *pInfo = p->pInfo;
17237 int rc;
17238 vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName);
17239 rc = p->pReal->pMethods->xSectorSize(p->pReal);
17240 vfstrace_printf(pInfo, " -> %d\n", rc);
17241 return rc;
17242 }
17243
17244 /*
17245 ** Return the device characteristic flags supported by an vfstrace-file.
17246 */
17247 static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
17248 vfstrace_file *p = (vfstrace_file *)pFile;
17249 vfstrace_info *pInfo = p->pInfo;
17250 int rc;
17251 vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)",
17252 pInfo->zVfsName, p->zFName);
17253 rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
17254 vfstrace_printf(pInfo, " -> 0x%08x\n", rc);
17255 return rc;
17256 }
17257
17258 /*
17259 ** Shared-memory operations.
17260 */
17261 static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
17262 vfstrace_file *p = (vfstrace_file *)pFile;
17263 vfstrace_info *pInfo = p->pInfo;
17264 int rc;
17265 char zLck[100];
17266 int i = 0;
17267 memcpy(zLck, "|0", 3);
17268 if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK");
17269 if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK");
17270 if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED");
17271 if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE");
17272 if( flags & ~(0xf) ){
17273 sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
17274 }
17275 vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
17276 pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
17277 rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
17278 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17279 return rc;
17280 }
17281 static int vfstraceShmMap(
17282 sqlite3_file *pFile,
17283 int iRegion,
17284 int szRegion,
17285 int isWrite,
17286 void volatile **pp
17287 ){
17288 vfstrace_file *p = (vfstrace_file *)pFile;
17289 vfstrace_info *pInfo = p->pInfo;
17290 int rc;
17291 vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)",
17292 pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite);
17293 rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
17294 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17295 return rc;
17296 }
17297 static void vfstraceShmBarrier(sqlite3_file *pFile){
17298 vfstrace_file *p = (vfstrace_file *)pFile;
17299 vfstrace_info *pInfo = p->pInfo;
17300 vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName);
17301 p->pReal->pMethods->xShmBarrier(p->pReal);
17302 }
17303 static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){
17304 vfstrace_file *p = (vfstrace_file *)pFile;
17305 vfstrace_info *pInfo = p->pInfo;
17306 int rc;
17307 vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
17308 pInfo->zVfsName, p->zFName, delFlag);
17309 rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
17310 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17311 return rc;
17312 }
17313
17314
17315
17316 /*
17317 ** Open an vfstrace file handle.
17318 */
17319 static int vfstraceOpen(
17320 sqlite3_vfs *pVfs,
17321 const char *zName,
17322 sqlite3_file *pFile,
17323 int flags,
17324 int *pOutFlags
17325 ){
17326 int rc;
17327 vfstrace_file *p = (vfstrace_file *)pFile;
17328 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17329 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17330 p->pInfo = pInfo;
17331 p->zFName = zName ? fileTail(zName) : "<temp>";
17332 p->pReal = (sqlite3_file *)&p[1];
17333 rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags);
17334 vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
17335 pInfo->zVfsName, p->zFName, flags);
17336 if( p->pReal->pMethods ){
17337 sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) );
17338 const sqlite3_io_methods *pSub = p->pReal->pMethods;
17339 memset(pNew, 0, sizeof(*pNew));
17340 pNew->iVersion = pSub->iVersion;
17341 pNew->xClose = vfstraceClose;
17342 pNew->xRead = vfstraceRead;
17343 pNew->xWrite = vfstraceWrite;
17344 pNew->xTruncate = vfstraceTruncate;
17345 pNew->xSync = vfstraceSync;
17346 pNew->xFileSize = vfstraceFileSize;
17347 pNew->xLock = vfstraceLock;
17348 pNew->xUnlock = vfstraceUnlock;
17349 pNew->xCheckReservedLock = vfstraceCheckReservedLock;
17350 pNew->xFileControl = vfstraceFileControl;
17351 pNew->xSectorSize = vfstraceSectorSize;
17352 pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics;
17353 if( pNew->iVersion>=2 ){
17354 pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0;
17355 pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0;
17356 pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0;
17357 pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0;
17358 }
17359 pFile->pMethods = pNew;
17360 }
17361 vfstrace_print_errcode(pInfo, " -> %s", rc);
17362 if( pOutFlags ){
17363 vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags);
17364 }else{
17365 vfstrace_printf(pInfo, "\n");
17366 }
17367 return rc;
17368 }
17369
17370 /*
17371 ** Delete the file located at zPath. If the dirSync argument is true,
17372 ** ensure the file-system modifications are synced to disk before
17373 ** returning.
17374 */
17375 static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
17376 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17377 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17378 int rc;
17379 vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
17380 pInfo->zVfsName, zPath, dirSync);
17381 rc = pRoot->xDelete(pRoot, zPath, dirSync);
17382 vfstrace_print_errcode(pInfo, " -> %s\n", rc);
17383 return rc;
17384 }
17385
17386 /*
17387 ** Test for access permissions. Return true if the requested permission
17388 ** is available, or false otherwise.
17389 */
17390 static int vfstraceAccess(
17391 sqlite3_vfs *pVfs,
17392 const char *zPath,
17393 int flags,
17394 int *pResOut
17395 ){
17396 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17397 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17398 int rc;
17399 vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)",
17400 pInfo->zVfsName, zPath, flags);
17401 rc = pRoot->xAccess(pRoot, zPath, flags, pResOut);
17402 vfstrace_print_errcode(pInfo, " -> %s", rc);
17403 vfstrace_printf(pInfo, ", out=%d\n", *pResOut);
17404 return rc;
17405 }
17406
17407 /*
17408 ** Populate buffer zOut with the full canonical pathname corresponding
17409 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
17410 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
17411 */
17412 static int vfstraceFullPathname(
17413 sqlite3_vfs *pVfs,
17414 const char *zPath,
17415 int nOut,
17416 char *zOut
17417 ){
17418 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17419 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17420 int rc;
17421 vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")",
17422 pInfo->zVfsName, zPath);
17423 rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut);
17424 vfstrace_print_errcode(pInfo, " -> %s", rc);
17425 vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut);
17426 return rc;
17427 }
17428
17429 /*
17430 ** Open the dynamic library located at zPath and return a handle.
17431 */
17432 static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
17433 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17434 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17435 vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath);
17436 return pRoot->xDlOpen(pRoot, zPath);
17437 }
17438
17439 /*
17440 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
17441 ** utf-8 string describing the most recent error encountered associated
17442 ** with dynamic libraries.
17443 */
17444 static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
17445 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17446 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17447 vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte);
17448 pRoot->xDlError(pRoot, nByte, zErrMsg);
17449 vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg);
17450 }
17451
17452 /*
17453 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
17454 */
17455 static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){
17456 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17457 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17458 vfstrace_printf(pInfo, "%s.xDlSym(\"%s\")\n", pInfo->zVfsName, zSym);
17459 return pRoot->xDlSym(pRoot, p, zSym);
17460 }
17461
17462 /*
17463 ** Close the dynamic library handle pHandle.
17464 */
17465 static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
17466 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17467 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17468 vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
17469 pRoot->xDlClose(pRoot, pHandle);
17470 }
17471
17472 /*
17473 ** Populate the buffer pointed to by zBufOut with nByte bytes of
17474 ** random data.
17475 */
17476 static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
17477 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17478 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17479 vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte);
17480 return pRoot->xRandomness(pRoot, nByte, zBufOut);
17481 }
17482
17483 /*
17484 ** Sleep for nMicro microseconds. Return the number of microseconds
17485 ** actually slept.
17486 */
17487 static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
17488 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17489 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17490 return pRoot->xSleep(pRoot, nMicro);
17491 }
17492
17493 /*
17494 ** Return the current time as a Julian Day number in *pTimeOut.
17495 */
17496 static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
17497 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17498 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17499 return pRoot->xCurrentTime(pRoot, pTimeOut);
17500 }
17501 static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
17502 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17503 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17504 return pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
17505 }
17506
17507 /*
17508 ** Return th3 most recent error code and message
17509 */
17510 static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){
17511 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17512 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17513 return pRoot->xGetLastError(pRoot, iErr, zErr);
17514 }
17515
17516 /*
17517 ** Override system calls.
17518 */
17519 static int vfstraceSetSystemCall(
17520 sqlite3_vfs *pVfs,
17521 const char *zName,
17522 sqlite3_syscall_ptr pFunc
17523 ){
17524 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17525 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17526 return pRoot->xSetSystemCall(pRoot, zName, pFunc);
17527 }
17528 static sqlite3_syscall_ptr vfstraceGetSystemCall(
17529 sqlite3_vfs *pVfs,
17530 const char *zName
17531 ){
17532 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17533 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17534 return pRoot->xGetSystemCall(pRoot, zName);
17535 }
17536 static const char *vfstraceNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
17537 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
17538 sqlite3_vfs *pRoot = pInfo->pRootVfs;
17539 return pRoot->xNextSystemCall(pRoot, zName);
17540 }
17541
17542
17543 /*
17544 ** Clients invoke this routine to construct a new trace-vfs shim.
17545 **
17546 ** Return SQLITE_OK on success.
17547 **
17548 ** SQLITE_NOMEM is returned in the case of a memory allocation error.
17549 ** SQLITE_NOTFOUND is returned if zOldVfsName does not exist.
17550 */
17551 int vfstrace_register(
17552 const char *zTraceName, /* Name of the newly constructed VFS */
17553 const char *zOldVfsName, /* Name of the underlying VFS */
17554 int (*xOut)(const char*,void*), /* Output routine. ex: fputs */
17555 void *pOutArg, /* 2nd argument to xOut. ex: stderr */
17556 int makeDefault /* True to make the new VFS the default */
17557 ){
17558 sqlite3_vfs *pNew;
17559 sqlite3_vfs *pRoot;
17560 vfstrace_info *pInfo;
17561 size_t nName;
17562 size_t nByte;
17563
17564 pRoot = sqlite3_vfs_find(zOldVfsName);
17565 if( pRoot==0 ) return SQLITE_NOTFOUND;
17566 nName = strlen(zTraceName);
17567 nByte = sizeof(*pNew) + sizeof(*pInfo) + nName + 1;
17568 pNew = sqlite3_malloc64( nByte );
17569 if( pNew==0 ) return SQLITE_NOMEM;
17570 memset(pNew, 0, nByte);
17571 pInfo = (vfstrace_info*)&pNew[1];
17572 pNew->iVersion = pRoot->iVersion;
17573 pNew->szOsFile = pRoot->szOsFile + sizeof(vfstrace_file);
17574 pNew->mxPathname = pRoot->mxPathname;
17575 pNew->zName = (char*)&pInfo[1];
17576 memcpy((char*)&pInfo[1], zTraceName, nName+1);
17577 pNew->pAppData = pInfo;
17578 pNew->xOpen = vfstraceOpen;
17579 pNew->xDelete = vfstraceDelete;
17580 pNew->xAccess = vfstraceAccess;
17581 pNew->xFullPathname = vfstraceFullPathname;
17582 pNew->xDlOpen = pRoot->xDlOpen==0 ? 0 : vfstraceDlOpen;
17583 pNew->xDlError = pRoot->xDlError==0 ? 0 : vfstraceDlError;
17584 pNew->xDlSym = pRoot->xDlSym==0 ? 0 : vfstraceDlSym;
17585 pNew->xDlClose = pRoot->xDlClose==0 ? 0 : vfstraceDlClose;
17586 pNew->xRandomness = vfstraceRandomness;
17587 pNew->xSleep = vfstraceSleep;
17588 pNew->xCurrentTime = vfstraceCurrentTime;
17589 pNew->xGetLastError = pRoot->xGetLastError==0 ? 0 : vfstraceGetLastError;
17590 if( pNew->iVersion>=2 ){
17591 pNew->xCurrentTimeInt64 = pRoot->xCurrentTimeInt64==0 ? 0 :
17592 vfstraceCurrentTimeInt64;
17593 if( pNew->iVersion>=3 ){
17594 pNew->xSetSystemCall = pRoot->xSetSystemCall==0 ? 0 :
17595 vfstraceSetSystemCall;
17596 pNew->xGetSystemCall = pRoot->xGetSystemCall==0 ? 0 :
17597 vfstraceGetSystemCall;
17598 pNew->xNextSystemCall = pRoot->xNextSystemCall==0 ? 0 :
17599 vfstraceNextSystemCall;
17600 }
17601 }
17602 pInfo->pRootVfs = pRoot;
17603 pInfo->xOut = xOut;
17604 pInfo->pOutArg = pOutArg;
17605 pInfo->zVfsName = pNew->zName;
17606 pInfo->pTraceVfs = pNew;
17607 vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n",
17608 pInfo->zVfsName, pRoot->zName);
17609 return sqlite3_vfs_register(pNew, makeDefault);
17610 }
17611
17612 /*
17613 ** Look for the named VFS. If it is a TRACEVFS, then unregister it
17614 ** and delete it.
17615 */
17616 void vfstrace_unregister(const char *zTraceName){
17617 sqlite3_vfs *pVfs = sqlite3_vfs_find(zTraceName);
17618 if( pVfs==0 ) return;
17619 if( pVfs->xOpen!=vfstraceOpen ) return;
17620 sqlite3_vfs_unregister(pVfs);
17621 sqlite3_free(pVfs);
17622 }
17623
17624 /************************* End ../ext/misc/vfstrace.c ********************/
17625
17626 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
17627 #define SQLITE_SHELL_HAVE_RECOVER 1
17628 #else
17629 #define SQLITE_SHELL_HAVE_RECOVER 0
@@ -24511,10 +25920,11 @@
25920 }
25921
25922 #ifndef SQLITE_OMIT_LOAD_EXTENSION
25923 sqlite3_enable_load_extension(p->db, 1);
25924 #endif
25925 sqlite3_sha_init(p->db, 0, 0);
25926 sqlite3_shathree_init(p->db, 0, 0);
25927 sqlite3_uint_init(p->db, 0, 0);
25928 sqlite3_stmtrand_init(p->db, 0, 0);
25929 sqlite3_decimal_init(p->db, 0, 0);
25930 sqlite3_percentile_init(p->db, 0, 0);
@@ -31374,13 +32784,11 @@
32784 " -table set output mode to 'table'\n"
32785 " -tabs set output mode to 'tabs'\n"
32786 " -unsafe-testing allow unsafe commands and modes for testing\n"
32787 " -version show SQLite version\n"
32788 " -vfs NAME use NAME as the default VFS\n"
 
32789 " -vfstrace enable tracing of all VFS calls\n"
 
32790 #ifdef SQLITE_HAVE_ZLIB
32791 " -zip open the file as a ZIP Archive\n"
32792 #endif
32793 ;
32794 static void usage(int showDetail){
@@ -31502,10 +32910,11 @@
32910 int rc = 0;
32911 int warnInmemoryDb = 0;
32912 int readStdin = 1;
32913 int nCmd = 0;
32914 int nOptsEnd = argc;
32915 int bEnableVfstrace = 0;
32916 char **azCmd = 0;
32917 const char *zVfs = 0; /* Value of -vfs command-line option */
32918 #if !SQLITE_SHELL_IS_UTF8
32919 char **argvToFree = 0;
32920 int argcToFree = 0;
@@ -31696,21 +33105,13 @@
33105 switch( n ){
33106 case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break;
33107 case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break;
33108 default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break;
33109 }
 
33110 }else if( cli_strcmp(z,"-vfstrace")==0 ){
 
 
 
 
 
 
 
33111 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
33112 bEnableVfstrace = 1;
33113 #ifdef SQLITE_ENABLE_MULTIPLEX
33114 }else if( cli_strcmp(z,"-multiplex")==0 ){
33115 extern int sqlite3_multiplex_initialize(const char*,int);
33116 sqlite3_multiplex_initialize(0, 1);
33117 #endif
@@ -31762,11 +33163,11 @@
33163 }else if( cli_strcmp(z,"-safe")==0 ){
33164 /* no-op - catch this on the second pass */
33165 }
33166 }
33167 #ifndef SQLITE_SHELL_FIDDLE
33168 if( !bEnableVfstrace ) verify_uninitialized();
33169 #endif
33170
33171
33172 #ifdef SQLITE_SHELL_INIT_PROC
33173 {
@@ -31951,14 +33352,12 @@
33352 }else if( cli_strcmp(z,"-sorterref")==0 ){
33353 i++;
33354 #endif
33355 }else if( cli_strcmp(z,"-vfs")==0 ){
33356 i++;
 
33357 }else if( cli_strcmp(z,"-vfstrace")==0 ){
33358 i++;
 
33359 #ifdef SQLITE_ENABLE_MULTIPLEX
33360 }else if( cli_strcmp(z,"-multiplex")==0 ){
33361 i++;
33362 #endif
33363 }else if( cli_strcmp(z,"-help")==0 ){
@@ -32122,10 +33521,13 @@
33521 free(data.colWidth);
33522 free(data.zNonce);
33523 /* Clear the global data structure so that valgrind will detect memory
33524 ** leaks */
33525 memset(&data, 0, sizeof(data));
33526 if( bEnableVfstrace ){
33527 vfstrace_unregister("trace");
33528 }
33529 #ifdef SQLITE_DEBUG
33530 if( sqlite3_memory_used()>mem_main_enter ){
33531 eputf("Memory leaked: %u bytes\n",
33532 (unsigned int)(sqlite3_memory_used()-mem_main_enter));
33533 }
33534
+524 -364
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
1616
** if you want a wrapper to interface SQLite with your choice of programming
1717
** language. The code for the "sqlite3" command-line shell is also in a
1818
** separate file. This file contains only code for the core SQLite library.
1919
**
2020
** The content in this amalgamation comes from Fossil check-in
21
-** 7891a266c4425722ae8b9231397ef9e42e24.
21
+** a63e412b6b2939422ecfa99d91fccb7a9c61.
2222
*/
2323
#define SQLITE_CORE 1
2424
#define SQLITE_AMALGAMATION 1
2525
#ifndef SQLITE_PRIVATE
2626
# define SQLITE_PRIVATE static
@@ -462,11 +462,11 @@
462462
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
463463
** [sqlite_version()] and [sqlite_source_id()].
464464
*/
465465
#define SQLITE_VERSION "3.47.0"
466466
#define SQLITE_VERSION_NUMBER 3047000
467
-#define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
467
+#define SQLITE_SOURCE_ID "2024-09-17 22:57:08 a63e412b6b2939422ecfa99d91fccb7a9c61e1533bb0db20ff12f3815ef41a2c"
468468
469469
/*
470470
** CAPI3REF: Run-Time Library Version Numbers
471471
** KEYWORDS: sqlite3_version sqlite3_sourceid
472472
**
@@ -29285,20 +29285,33 @@
2928529285
2928629286
#ifndef NDEBUG
2928729287
/*
2928829288
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
2928929289
** intended for use inside assert() statements.
29290
+**
29291
+** Because these routines raise false-positive alerts in TSAN, disable
29292
+** them (make them always return 1) when compiling with TSAN.
2929029293
*/
2929129294
SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
29295
+# if defined(__has_feature)
29296
+# if __has_feature(thread_sanitizer)
29297
+ p = 0;
29298
+# endif
29299
+# endif
2929229300
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
2929329301
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
2929429302
}
2929529303
SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
29304
+# if defined(__has_feature)
29305
+# if __has_feature(thread_sanitizer)
29306
+ p = 0;
29307
+# endif
29308
+# endif
2929629309
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
2929729310
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
2929829311
}
29299
-#endif
29312
+#endif /* NDEBUG */
2930029313
2930129314
#endif /* !defined(SQLITE_MUTEX_OMIT) */
2930229315
2930329316
/************** End of mutex.c ***********************************************/
2930429317
/************** Begin file mutex_noop.c **************************************/
@@ -65171,11 +65184,11 @@
6517165184
** 20: Salt-2, a different random integer changing with each ckpt
6517265185
** 24: Checksum-1 (first part of checksum for first 24 bytes of header).
6517365186
** 28: Checksum-2 (second part of checksum for first 24 bytes of header).
6517465187
**
6517565188
** Immediately following the wal-header are zero or more frames. Each
65176
-** frame consists of a 24-byte frame-header followed by a <page-size> bytes
65189
+** frame consists of a 24-byte frame-header followed by <page-size> bytes
6517765190
** of page data. The frame-header is six big-endian 32-bit unsigned
6517865191
** integer values, as follows:
6517965192
**
6518065193
** 0: Page number.
6518165194
** 4: For commit records, the size of the database image in pages
@@ -92230,10 +92243,21 @@
9223092243
** A successful evaluation of this routine acquires the mutex on p.
9223192244
** the mutex is released if any kind of error occurs.
9223292245
**
9223392246
** The error code stored in database p->db is overwritten with the return
9223492247
** value in any case.
92248
+**
92249
+** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK,
92250
+** that means all of the the following will be true:
92251
+**
92252
+** p!=0
92253
+** p->pVar!=0
92254
+** i>0
92255
+** i<=p->nVar
92256
+**
92257
+** An assert() is normally added after vdbeUnbind() to help static analyzers
92258
+** realize this.
9223592259
*/
9223692260
static int vdbeUnbind(Vdbe *p, unsigned int i){
9223792261
Mem *pVar;
9223892262
if( vdbeSafetyNotNull(p) ){
9223992263
return SQLITE_MISUSE_BKPT;
@@ -92287,10 +92311,11 @@
9228792311
Mem *pVar;
9228892312
int rc;
9228992313
9229092314
rc = vdbeUnbind(p, (u32)(i-1));
9229192315
if( rc==SQLITE_OK ){
92316
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
9229292317
if( zData!=0 ){
9229392318
pVar = &p->aVar[i-1];
9229492319
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
9229592320
if( rc==SQLITE_OK && encoding!=0 ){
9229692321
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
@@ -92336,10 +92361,11 @@
9233692361
SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
9233792362
int rc;
9233892363
Vdbe *p = (Vdbe *)pStmt;
9233992364
rc = vdbeUnbind(p, (u32)(i-1));
9234092365
if( rc==SQLITE_OK ){
92366
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
9234192367
sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
9234292368
sqlite3_mutex_leave(p->db->mutex);
9234392369
}
9234492370
return rc;
9234592371
}
@@ -92349,10 +92375,11 @@
9234992375
SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
9235092376
int rc;
9235192377
Vdbe *p = (Vdbe *)pStmt;
9235292378
rc = vdbeUnbind(p, (u32)(i-1));
9235392379
if( rc==SQLITE_OK ){
92380
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
9235492381
sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
9235592382
sqlite3_mutex_leave(p->db->mutex);
9235692383
}
9235792384
return rc;
9235892385
}
@@ -92359,10 +92386,11 @@
9235992386
SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
9236092387
int rc;
9236192388
Vdbe *p = (Vdbe*)pStmt;
9236292389
rc = vdbeUnbind(p, (u32)(i-1));
9236392390
if( rc==SQLITE_OK ){
92391
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
9236492392
sqlite3_mutex_leave(p->db->mutex);
9236592393
}
9236692394
return rc;
9236792395
}
9236892396
SQLITE_API int sqlite3_bind_pointer(
@@ -92374,10 +92402,11 @@
9237492402
){
9237592403
int rc;
9237692404
Vdbe *p = (Vdbe*)pStmt;
9237792405
rc = vdbeUnbind(p, (u32)(i-1));
9237892406
if( rc==SQLITE_OK ){
92407
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
9237992408
sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
9238092409
sqlite3_mutex_leave(p->db->mutex);
9238192410
}else if( xDestructor ){
9238292411
xDestructor(pPtr);
9238392412
}
@@ -92455,10 +92484,11 @@
9245592484
SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
9245692485
int rc;
9245792486
Vdbe *p = (Vdbe *)pStmt;
9245892487
rc = vdbeUnbind(p, (u32)(i-1));
9245992488
if( rc==SQLITE_OK ){
92489
+ assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
9246092490
#ifndef SQLITE_OMIT_INCRBLOB
9246192491
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
9246292492
#else
9246392493
rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
9246492494
#endif
@@ -169140,10 +169170,11 @@
169140169170
hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0;
169141169171
for(i=pWInfo->nLevel-1; i>=1; i--){
169142169172
WhereTerm *pTerm, *pEnd;
169143169173
SrcItem *pItem;
169144169174
WhereLoop *pLoop;
169175
+ Bitmask m1;
169145169176
pLoop = pWInfo->a[i].pWLoop;
169146169177
pItem = &pWInfo->pTabList->a[pLoop->iTab];
169147169178
if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
169148169179
if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0
169149169180
&& (pLoop->wsFlags & WHERE_ONEROW)==0
@@ -169166,11 +169197,14 @@
169166169197
){
169167169198
break; /* restriction (5) */
169168169199
}
169169169200
}
169170169201
if( pTerm<pEnd ) continue;
169171
- WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId));
169202
+ WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId));
169203
+ m1 = MASKBIT(i)-1;
169204
+ testcase( ((pWInfo->revMask>>1) & ~m1)!=0 );
169205
+ pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1);
169172169206
notReady &= ~pLoop->maskSelf;
169173169207
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
169174169208
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
169175169209
pTerm->wtFlags |= TERM_CODED;
169176169210
}
@@ -208867,11 +208901,13 @@
208867208901
int rawKey = 1;
208868208902
x = pParse->aBlob[iRoot];
208869208903
zPath++;
208870208904
if( zPath[0]=='"' ){
208871208905
zKey = zPath + 1;
208872
- for(i=1; zPath[i] && zPath[i]!='"'; i++){}
208906
+ for(i=1; zPath[i] && zPath[i]!='"'; i++){
208907
+ if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++;
208908
+ }
208873208909
nKey = i-1;
208874208910
if( zPath[i] ){
208875208911
i++;
208876208912
}else{
208877208913
return JSON_LOOKUP_PATHERROR;
@@ -219628,10 +219664,31 @@
219628219664
struct RbuFrame {
219629219665
u32 iDbPage;
219630219666
u32 iWalFrame;
219631219667
};
219632219668
219669
+#ifndef UNUSED_PARAMETER
219670
+/*
219671
+** The following macros are used to suppress compiler warnings and to
219672
+** make it clear to human readers when a function parameter is deliberately
219673
+** left unused within the body of a function. This usually happens when
219674
+** a function is called via a function pointer. For example the
219675
+** implementation of an SQL aggregate step callback may not use the
219676
+** parameter indicating the number of arguments passed to the aggregate,
219677
+** if it knows that this is enforced elsewhere.
219678
+**
219679
+** When a function parameter is not used at all within the body of a function,
219680
+** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
219681
+** However, these macros may also be used to suppress warnings related to
219682
+** parameters that may or may not be used depending on compilation options.
219683
+** For example those parameters only used in assert() statements. In these
219684
+** cases the parameters are named as per the usual conventions.
219685
+*/
219686
+#define UNUSED_PARAMETER(x) (void)(x)
219687
+#define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
219688
+#endif
219689
+
219633219690
/*
219634219691
** RBU handle.
219635219692
**
219636219693
** nPhaseOneStep:
219637219694
** If the RBU database contains an rbu_count table, this value is set to
@@ -219679,11 +219736,11 @@
219679219736
char *zState; /* Path to state db (or NULL if zRbu) */
219680219737
char zStateDb[5]; /* Db name for state ("stat" or "main") */
219681219738
int rc; /* Value returned by last rbu_step() call */
219682219739
char *zErrmsg; /* Error message if rc!=SQLITE_OK */
219683219740
int nStep; /* Rows processed for current object */
219684
- int nProgress; /* Rows processed for all objects */
219741
+ sqlite3_int64 nProgress; /* Rows processed for all objects */
219685219742
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
219686219743
const char *zVfsName; /* Name of automatically created rbu vfs */
219687219744
rbu_file *pTargetFd; /* File handle open on target db */
219688219745
int nPagePerSector; /* Pages per sector for pTargetFd */
219689219746
i64 iOalSz;
@@ -219796,11 +219853,11 @@
219796219853
unsigned char *zStart = z;
219797219854
while( (c = zValue[0x7f&*(z++)])>=0 ){
219798219855
v = (v<<6) + c;
219799219856
}
219800219857
z--;
219801
- *pLen -= z - zStart;
219858
+ *pLen -= (int)(z - zStart);
219802219859
*pz = (char*)z;
219803219860
return v;
219804219861
}
219805219862
219806219863
#if RBU_ENABLE_DELTA_CKSUM
@@ -219981,10 +220038,11 @@
219981220038
int nOut;
219982220039
int nOut2;
219983220040
char *aOut;
219984220041
219985220042
assert( argc==2 );
220043
+ UNUSED_PARAMETER(argc);
219986220044
219987220045
nOrig = sqlite3_value_bytes(argv[0]);
219988220046
aOrig = (const char*)sqlite3_value_blob(argv[0]);
219989220047
nDelta = sqlite3_value_bytes(argv[1]);
219990220048
aDelta = (const char*)sqlite3_value_blob(argv[1]);
@@ -221560,17 +221618,17 @@
221560221618
nParen++;
221561221619
}
221562221620
else if( c==')' ){
221563221621
nParen--;
221564221622
if( nParen==0 ){
221565
- int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
221623
+ int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
221566221624
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
221567221625
i++;
221568221626
break;
221569221627
}
221570221628
}else if( c==',' && nParen==1 ){
221571
- int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
221629
+ int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
221572221630
pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
221573221631
pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
221574221632
}else if( c=='"' || c=='\'' || c=='`' ){
221575221633
for(i++; 1; i++){
221576221634
if( zSql[i]==c ){
@@ -222256,10 +222314,12 @@
222256222314
int i, sz;
222257222315
sz = (int)strlen(z)&0xffffff;
222258222316
for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
222259222317
if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
222260222318
}
222319
+#else
222320
+ UNUSED_PARAMETER2(zBase,z);
222261222321
#endif
222262222322
}
222263222323
222264222324
/*
222265222325
** Return the current wal-index header checksum for the target database
@@ -222840,11 +222900,11 @@
222840222900
"INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES "
222841222901
"(%d, %d), "
222842222902
"(%d, %Q), "
222843222903
"(%d, %Q), "
222844222904
"(%d, %d), "
222845
- "(%d, %d), "
222905
+ "(%d, %lld), "
222846222906
"(%d, %lld), "
222847222907
"(%d, %lld), "
222848222908
"(%d, %lld), "
222849222909
"(%d, %lld), "
222850222910
"(%d, %Q) ",
@@ -223198,10 +223258,11 @@
223198223258
char *zErrmsg = 0;
223199223259
int rc;
223200223260
sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
223201223261
223202223262
assert( nVal==1 );
223263
+ UNUSED_PARAMETER(nVal);
223203223264
223204223265
rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
223205223266
sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
223206223267
"WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
223207223268
);
@@ -223473,11 +223534,11 @@
223473223534
const char *zTarget,
223474223535
const char *zState
223475223536
){
223476223537
if( zTarget==0 ){ return rbuMisuseError(); }
223477223538
if( zState ){
223478
- int n = strlen(zState);
223539
+ size_t n = strlen(zState);
223479223540
if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
223480223541
return rbuMisuseError();
223481223542
}
223482223543
}
223483223544
/* TODO: Check that both arguments are non-NULL */
@@ -223690,10 +223751,11 @@
223690223751
/*
223691223752
** Default xRename callback for RBU.
223692223753
*/
223693223754
static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
223694223755
int rc = SQLITE_OK;
223756
+ UNUSED_PARAMETER(pArg);
223695223757
#if defined(_WIN32_WCE)
223696223758
{
223697223759
LPWSTR zWideOld;
223698223760
LPWSTR zWideNew;
223699223761
@@ -224594,10 +224656,13 @@
224594224656
224595224657
/*
224596224658
** No-op.
224597224659
*/
224598224660
static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
224661
+ UNUSED_PARAMETER(pVfs);
224662
+ UNUSED_PARAMETER(a);
224663
+ UNUSED_PARAMETER(b);
224599224664
return 0;
224600224665
}
224601224666
224602224667
/*
224603224668
** Deregister and destroy an RBU vfs created by an earlier call to
@@ -225650,11 +225715,17 @@
225650225715
** schema for the database file that is to be read. The default schema is
225651225716
** "main".
225652225717
**
225653225718
** The data field of sqlite_dbpage table can be updated. The new
225654225719
** value must be a BLOB which is the correct page size, otherwise the
225655
-** update fails. Rows may not be deleted or inserted.
225720
+** update fails. INSERT operations also work, and operate as if they
225721
+** where REPLACE. The size of the database can be extended by INSERT-ing
225722
+** new pages on the end.
225723
+**
225724
+** Rows may not be deleted. However, doing an INSERT to page number N
225725
+** with NULL page data causes the N-th page and all subsequent pages to be
225726
+** deleted and the database to be truncated.
225656225727
*/
225657225728
225658225729
/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
225659225730
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
225660225731
&& !defined(SQLITE_OMIT_VIRTUALTABLE)
@@ -225673,17 +225744,18 @@
225673225744
};
225674225745
225675225746
struct DbpageTable {
225676225747
sqlite3_vtab base; /* Base class. Must be first */
225677225748
sqlite3 *db; /* The database */
225749
+ int nTrunc; /* Entries in aTrunc[] */
225750
+ Pgno *aTrunc; /* Truncation size for each database */
225678225751
};
225679225752
225680225753
/* Columns */
225681225754
#define DBPAGE_COLUMN_PGNO 0
225682225755
#define DBPAGE_COLUMN_DATA 1
225683225756
#define DBPAGE_COLUMN_SCHEMA 2
225684
-
225685225757
225686225758
225687225759
/*
225688225760
** Connect to or create a dbpagevfs virtual table.
225689225761
*/
@@ -225722,10 +225794,12 @@
225722225794
225723225795
/*
225724225796
** Disconnect from or destroy a dbpagevfs virtual table.
225725225797
*/
225726225798
static int dbpageDisconnect(sqlite3_vtab *pVtab){
225799
+ DbpageTable *pTab = (DbpageTable *)pVtab;
225800
+ sqlite3_free(pTab->aTrunc);
225727225801
sqlite3_free(pVtab);
225728225802
return SQLITE_OK;
225729225803
}
225730225804
225731225805
/*
@@ -225943,15 +226017,15 @@
225943226017
DbpageTable *pTab = (DbpageTable *)pVtab;
225944226018
Pgno pgno;
225945226019
DbPage *pDbPage = 0;
225946226020
int rc = SQLITE_OK;
225947226021
char *zErr = 0;
225948
- const char *zSchema;
225949226022
int iDb;
225950226023
Btree *pBt;
225951226024
Pager *pPager;
225952226025
int szPage;
226026
+ int isInsert;
225953226027
225954226028
(void)pRowid;
225955226029
if( pTab->db->flags & SQLITE_Defensive ){
225956226030
zErr = "read-only";
225957226031
goto update_fail;
@@ -225958,44 +226032,65 @@
225958226032
}
225959226033
if( argc==1 ){
225960226034
zErr = "cannot delete";
225961226035
goto update_fail;
225962226036
}
225963
- pgno = sqlite3_value_int(argv[0]);
225964
- if( sqlite3_value_type(argv[0])==SQLITE_NULL
225965
- || (Pgno)sqlite3_value_int(argv[1])!=pgno
225966
- ){
225967
- zErr = "cannot insert";
225968
- goto update_fail;
225969
- }
225970
- zSchema = (const char*)sqlite3_value_text(argv[4]);
225971
- iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1;
225972
- if( NEVER(iDb<0) ){
225973
- zErr = "no such schema";
225974
- goto update_fail;
226037
+ if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
226038
+ pgno = (Pgno)sqlite3_value_int(argv[2]);
226039
+ isInsert = 1;
226040
+ }else{
226041
+ pgno = sqlite3_value_int(argv[0]);
226042
+ if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
226043
+ zErr = "cannot insert";
226044
+ goto update_fail;
226045
+ }
226046
+ isInsert = 0;
226047
+ }
226048
+ if( sqlite3_value_type(argv[4])==SQLITE_NULL ){
226049
+ iDb = 0;
226050
+ }else{
226051
+ const char *zSchema = (const char*)sqlite3_value_text(argv[4]);
226052
+ iDb = sqlite3FindDbName(pTab->db, zSchema);
226053
+ if( iDb<0 ){
226054
+ zErr = "no such schema";
226055
+ goto update_fail;
226056
+ }
225975226057
}
225976226058
pBt = pTab->db->aDb[iDb].pBt;
225977
- if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){
226059
+ if( pgno<1 || NEVER(pBt==0) ){
225978226060
zErr = "bad page number";
225979226061
goto update_fail;
225980226062
}
225981226063
szPage = sqlite3BtreeGetPageSize(pBt);
225982226064
if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
225983226065
|| sqlite3_value_bytes(argv[3])!=szPage
225984226066
){
225985
- zErr = "bad page value";
225986
- goto update_fail;
226067
+ if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert ){
226068
+ if( iDb>=pTab->nTrunc ){
226069
+ testcase( pTab->aTrunc!=0 );
226070
+ pTab->aTrunc = sqlite3_realloc(pTab->aTrunc, (iDb+1)*sizeof(Pgno));
226071
+ if( pTab->aTrunc ){
226072
+ int j;
226073
+ for(j=pTab->nTrunc; j<iDb; j++) pTab->aTrunc[j] = 0;
226074
+ pTab->nTrunc = iDb+1;
226075
+ }else{
226076
+ return SQLITE_NOMEM;
226077
+ }
226078
+ }
226079
+ pTab->aTrunc[iDb] = pgno;
226080
+ }else{
226081
+ zErr = "bad page value";
226082
+ goto update_fail;
226083
+ }
225987226084
}
225988226085
pPager = sqlite3BtreePager(pBt);
225989226086
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
225990226087
if( rc==SQLITE_OK ){
225991226088
const void *pData = sqlite3_value_blob(argv[3]);
225992
- assert( pData!=0 || pTab->db->mallocFailed );
225993
- if( pData
225994
- && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK
225995
- ){
225996
- memcpy(sqlite3PagerGetData(pDbPage), pData, szPage);
226089
+ if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
226090
+ unsigned char *aPage = sqlite3PagerGetData(pDbPage);
226091
+ memcpy(aPage, pData, szPage);
225997226092
}
225998226093
}
225999226094
sqlite3PagerUnref(pDbPage);
226000226095
return rc;
226001226096
@@ -226014,10 +226109,30 @@
226014226109
sqlite3 *db = pTab->db;
226015226110
int i;
226016226111
for(i=0; i<db->nDb; i++){
226017226112
Btree *pBt = db->aDb[i].pBt;
226018226113
if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
226114
+ }
226115
+ if( pTab->nTrunc>0 ){
226116
+ memset(pTab->aTrunc, 0, sizeof(pTab->aTrunc[0])*pTab->nTrunc);
226117
+ }
226118
+ return SQLITE_OK;
226119
+}
226120
+
226121
+/* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT
226122
+*/
226123
+static int dbpageSync(sqlite3_vtab *pVtab){
226124
+ int iDb;
226125
+ DbpageTable *pTab = (DbpageTable *)pVtab;
226126
+
226127
+ for(iDb=0; iDb<pTab->nTrunc; iDb++){
226128
+ if( pTab->aTrunc[iDb]>0 ){
226129
+ Btree *pBt = pTab->db->aDb[iDb].pBt;
226130
+ Pager *pPager = sqlite3BtreePager(pBt);
226131
+ sqlite3PagerTruncateImage(pPager, pTab->aTrunc[iDb]);
226132
+ pTab->aTrunc[iDb] = 0;
226133
+ }
226019226134
}
226020226135
return SQLITE_OK;
226021226136
}
226022226137
226023226138
@@ -226039,11 +226154,11 @@
226039226154
dbpageEof, /* xEof - check for end of scan */
226040226155
dbpageColumn, /* xColumn - read data */
226041226156
dbpageRowid, /* xRowid - read data */
226042226157
dbpageUpdate, /* xUpdate */
226043226158
dbpageBegin, /* xBegin */
226044
- 0, /* xSync */
226159
+ dbpageSync, /* xSync */
226045226160
0, /* xCommit */
226046226161
0, /* xRollback */
226047226162
0, /* xFindMethod */
226048226163
0, /* xRename */
226049226164
0, /* xSavepoint */
@@ -233972,20 +234087,17 @@
233972234087
233973234088
static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
233974234089
233975234090
static int sqlite3Fts5FlushToDisk(Fts5Table*);
233976234091
233977
-static int sqlite3Fts5ExtractText(
233978
- Fts5Config *pConfig,
233979
- sqlite3_value *pVal, /* Value to extract text from */
233980
- int bContent, /* Loaded from content table */
233981
- int *pbResetTokenizer, /* OUT: True if ClearLocale() required */
233982
- const char **ppText, /* OUT: Pointer to text buffer */
233983
- int *pnText /* OUT: Size of (*ppText) in bytes */
233984
-);
233985
-
233986234092
static void sqlite3Fts5ClearLocale(Fts5Config *pConfig);
234093
+static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc);
234094
+
234095
+static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal);
234096
+static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal,
234097
+ const char **ppText, int *pnText, const char **ppLoc, int *pnLoc
234098
+);
233987234099
233988234100
/*
233989234101
** End of interface to code in fts5.c.
233990234102
**************************************************************************/
233991234103
@@ -237544,10 +237656,19 @@
237544237656
sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
237545237657
}else{
237546237658
sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
237547237659
}
237548237660
}
237661
+ }
237662
+ if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){
237663
+ for(i=0; i<p->nCol; i++){
237664
+ if( p->abUnindexed[i]==0 ){
237665
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i);
237666
+ }else{
237667
+ sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL");
237668
+ }
237669
+ }
237549237670
}
237550237671
237551237672
assert( p->zContentExprlist==0 );
237552237673
p->zContentExprlist = (char*)buf.p;
237553237674
return rc;
@@ -251113,11 +251234,20 @@
251113251234
i64 iNextId; /* Used to allocate unique cursor ids */
251114251235
Fts5Auxiliary *pAux; /* First in list of all aux. functions */
251115251236
Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
251116251237
Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
251117251238
Fts5Cursor *pCsr; /* First in list of all open cursors */
251239
+ u32 aLocaleHdr[4];
251118251240
};
251241
+
251242
+/*
251243
+** Size of header on fts5_locale() values. And macro to access a buffer
251244
+** containing a copy of the header from an Fts5Config pointer.
251245
+*/
251246
+#define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
251247
+#define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
251248
+
251119251249
251120251250
/*
251121251251
** Each auxiliary function registered with the FTS5 module is represented
251122251252
** by an object of the following type. All such objects are stored as part
251123251253
** of the Fts5Global.pAux list.
@@ -251277,16 +251407,10 @@
251277251407
#define FTS5CSR_REQUIRE_POSLIST 0x40
251278251408
251279251409
#define BitFlagAllTest(x,y) (((x) & (y))==(y))
251280251410
#define BitFlagTest(x,y) (((x) & (y))!=0)
251281251411
251282
-/*
251283
-** The subtype value and header bytes used by fts5_locale().
251284
-*/
251285
-#define FTS5_LOCALE_SUBTYPE ((unsigned int)'L')
251286
-#define FTS5_LOCALE_HEADER "\x00\xE0\xB2\xEB"
251287
-
251288251412
251289251413
/*
251290251414
** Macros to Set(), Clear() and Test() cursor flags.
251291251415
*/
251292251416
#define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
@@ -252286,11 +252410,11 @@
252286252410
** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale
252287252411
** specified by pLocale/nLocale. The buffer indicated by pLocale must remain
252288252412
** valid until after the final call to sqlite3Fts5Tokenize() that will use
252289252413
** the locale.
252290252414
*/
252291
-static void fts5SetLocale(
252415
+static void sqlite3Fts5SetLocale(
252292252416
Fts5Config *pConfig,
252293252417
const char *zLocale,
252294252418
int nLocale
252295252419
){
252296252420
Fts5TokenizerConfig *pT = &pConfig->t;
@@ -252297,141 +252421,88 @@
252297252421
pT->pLocale = zLocale;
252298252422
pT->nLocale = nLocale;
252299252423
}
252300252424
252301252425
/*
252302
-** Clear any locale configured by an earlier call to fts5SetLocale() or
252303
-** sqlite3Fts5ExtractText().
252426
+** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale().
252304252427
*/
252305252428
static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
252306
- fts5SetLocale(pConfig, 0, 0);
252429
+ sqlite3Fts5SetLocale(pConfig, 0, 0);
252307252430
}
252308252431
252309252432
/*
252310
-** This function is used to extract utf-8 text from an sqlite3_value. This
252311
-** is usually done in order to tokenize it. For example, when:
252312
-**
252313
-** * a value is written to an fts5 table,
252314
-** * a value is deleted from an FTS5_CONTENT_NORMAL table,
252315
-** * a value containing a query expression is passed to xFilter()
252316
-**
252317
-** and so on.
252318
-**
252319
-** This function handles 2 cases:
252320
-**
252321
-** 1) Ordinary values. The text can be extracted from these using
252322
-** sqlite3_value_text().
252323
-**
252324
-** 2) Combination text/locale blobs created by fts5_locale(). There
252325
-** are several cases for these:
252326
-**
252327
-** * Blobs tagged with FTS5_LOCALE_SUBTYPE.
252328
-** * Blobs read from the content table of a locale=1 external-content
252329
-** table, and
252330
-** * Blobs read from the content table of a locale=1 regular
252331
-** content table.
252332
-**
252333
-** The first two cases above should have the 4 byte FTS5_LOCALE_HEADER
252334
-** header. It is an error if a blob with the subtype or a blob read
252335
-** from the content table of an external content table does not have
252336
-** the required header. A blob read from the content table of a regular
252337
-** locale=1 table does not have the header. This is to save space.
252338
-**
252339
-** If successful, SQLITE_OK is returned and output parameters (*ppText)
252340
-** and (*pnText) are set to point to a buffer containing the extracted utf-8
252341
-** text and its length in bytes, respectively. The buffer is not
252342
-** nul-terminated. It has the same lifetime as the sqlite3_value object
252343
-** from which it is extracted.
252344
-**
252345
-** Parameter bContent must be true if the value was read from an indexed
252346
-** column (i.e. not UNINDEXED) of the on disk content.
252347
-**
252348
-** If pbResetTokenizer is not NULL and if case (2) is used, then
252349
-** fts5SetLocale() is called to ensure subsequent sqlite3Fts5Tokenize() calls
252350
-** use the locale. In this case (*pbResetTokenizer) is set to true before
252351
-** returning, to indicate that the caller must call sqlite3Fts5ClearLocale()
252352
-** to clear the locale after tokenizing the text.
252433
+** Return true if the value passed as the only argument is an
252434
+** fts5_locale() value.
252353252435
*/
252354
-static int sqlite3Fts5ExtractText(
252355
- Fts5Config *pConfig,
252356
- sqlite3_value *pVal, /* Value to extract text from */
252357
- int bContent, /* True if indexed table content */
252358
- int *pbResetTokenizer, /* OUT: True if xSetLocale(NULL) required */
252359
- const char **ppText, /* OUT: Pointer to text buffer */
252360
- int *pnText /* OUT: Size of (*ppText) in bytes */
252361
-){
252362
- const char *pText = 0;
252363
- int nText = 0;
252364
- int rc = SQLITE_OK;
252365
- int bDecodeBlob = 0;
252366
-
252367
- assert( pbResetTokenizer==0 || *pbResetTokenizer==0 );
252368
- assert( bContent==0 || pConfig->eContent!=FTS5_CONTENT_NONE );
252369
- assert( bContent==0 || sqlite3_value_subtype(pVal)==0 );
252370
-
252436
+static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){
252437
+ int ret = 0;
252371252438
if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
252372
- if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE
252373
- || (bContent && pConfig->bLocale)
252374
- ){
252375
- bDecodeBlob = 1;
252376
- }
252377
- }
252378
-
252379
- if( bDecodeBlob ){
252380
- const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
252439
+ /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case.
252440
+ ** If the blob was created using zeroblob(), then sqlite3_value_blob()
252441
+ ** may call malloc(). If this malloc() fails, then the values returned
252442
+ ** by both value_blob() and value_bytes() will be 0. If value_bytes() were
252443
+ ** called first, then the NULL pointer returned by value_blob() might
252444
+ ** be dereferenced. */
252381252445
const u8 *pBlob = sqlite3_value_blob(pVal);
252382252446
int nBlob = sqlite3_value_bytes(pVal);
252383
-
252384
- /* Unless this blob was read from the %_content table of an
252385
- ** FTS5_CONTENT_NORMAL table, it should have the 4 byte fts5_locale()
252386
- ** header. Check for this. If it is not found, return an error. */
252387
- if( (!bContent || pConfig->eContent!=FTS5_CONTENT_NORMAL) ){
252388
- if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
252389
- rc = SQLITE_ERROR;
252390
- }else{
252391
- pBlob += 4;
252392
- nBlob -= 4;
252393
- }
252394
- }
252395
-
252396
- if( rc==SQLITE_OK ){
252397
- int nLocale = 0;
252398
-
252399
- for(nLocale=0; nLocale<nBlob; nLocale++){
252400
- if( pBlob[nLocale]==0x00 ) break;
252401
- }
252402
- if( nLocale==nBlob || nLocale==0 ){
252403
- rc = SQLITE_ERROR;
252404
- }else{
252405
- pText = (const char*)&pBlob[nLocale+1];
252406
- nText = nBlob-nLocale-1;
252407
-
252408
- if( pbResetTokenizer ){
252409
- fts5SetLocale(pConfig, (const char*)pBlob, nLocale);
252410
- *pbResetTokenizer = 1;
252411
- }
252412
- }
252413
- }
252414
-
252415
- }else{
252416
- pText = (const char*)sqlite3_value_text(pVal);
252417
- nText = sqlite3_value_bytes(pVal);
252418
- }
252419
-
252420
- *ppText = pText;
252421
- *pnText = nText;
252422
- return rc;
252447
+ if( nBlob>FTS5_LOCALE_HDR_SIZE
252448
+ && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE)
252449
+ ){
252450
+ ret = 1;
252451
+ }
252452
+ }
252453
+ return ret;
252454
+}
252455
+
252456
+/*
252457
+** Value pVal is guaranteed to be an fts5_locale() value, according to
252458
+** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale
252459
+** from the value and returns them separately.
252460
+**
252461
+** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set
252462
+** to point to buffers containing the text and locale, as utf-8,
252463
+** respectively. In this case output parameters (*pnText) and (*pnLoc) are
252464
+** set to the sizes in bytes of these two buffers.
252465
+**
252466
+** Or, if an error occurs, then an SQLite error code is returned. The final
252467
+** value of the four output parameters is undefined in this case.
252468
+*/
252469
+static int sqlite3Fts5DecodeLocaleValue(
252470
+ sqlite3_value *pVal,
252471
+ const char **ppText,
252472
+ int *pnText,
252473
+ const char **ppLoc,
252474
+ int *pnLoc
252475
+){
252476
+ const char *p = sqlite3_value_blob(pVal);
252477
+ int n = sqlite3_value_bytes(pVal);
252478
+ int nLoc = 0;
252479
+
252480
+ assert( sqlite3_value_type(pVal)==SQLITE_BLOB );
252481
+ assert( n>FTS5_LOCALE_HDR_SIZE );
252482
+
252483
+ for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){
252484
+ if( nLoc==(n-1) ){
252485
+ return SQLITE_MISMATCH;
252486
+ }
252487
+ }
252488
+ *ppLoc = &p[FTS5_LOCALE_HDR_SIZE];
252489
+ *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE;
252490
+
252491
+ *ppText = &p[nLoc+1];
252492
+ *pnText = n - nLoc - 1;
252493
+ return SQLITE_OK;
252423252494
}
252424252495
252425252496
/*
252426252497
** Argument pVal is the text of a full-text search expression. It may or
252427252498
** may not have been wrapped by fts5_locale(). This function extracts
252428252499
** the text of the expression, and sets output variable (*pzText) to
252429252500
** point to a nul-terminated buffer containing the expression.
252430252501
**
252431
-** If pVal was an fts5_locale() value, then fts5SetLocale() is called to
252432
-** set the tokenizer to use the specified locale.
252502
+** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called
252503
+** to set the tokenizer to use the specified locale.
252433252504
**
252434252505
** If output variable (*pbFreeAndReset) is set to true, then the caller
252435252506
** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
252436252507
** locale, and (b) call sqlite3_free() to free (*pzText).
252437252508
*/
@@ -252439,28 +252510,26 @@
252439252510
Fts5Config *pConfig, /* Fts5 configuration */
252440252511
sqlite3_value *pVal, /* Value to extract expression text from */
252441252512
char **pzText, /* OUT: nul-terminated buffer of text */
252442252513
int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */
252443252514
){
252444
- const char *zText = 0;
252445
- int nText = 0;
252446252515
int rc = SQLITE_OK;
252447
- int bReset = 0;
252448
-
252449
- *pbFreeAndReset = 0;
252450
- rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, &bReset, &zText, &nText);
252451
- if( rc==SQLITE_OK ){
252452
- if( bReset ){
252453
- *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, zText);
252454
- if( rc!=SQLITE_OK ){
252455
- sqlite3Fts5ClearLocale(pConfig);
252456
- }else{
252457
- *pbFreeAndReset = 1;
252458
- }
252459
- }else{
252460
- *pzText = (char*)zText;
252461
- }
252516
+
252517
+ if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
252518
+ const char *pText = 0;
252519
+ int nText = 0;
252520
+ const char *pLoc = 0;
252521
+ int nLoc = 0;
252522
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
252523
+ *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText);
252524
+ if( rc==SQLITE_OK ){
252525
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
252526
+ }
252527
+ *pbFreeAndReset = 1;
252528
+ }else{
252529
+ *pzText = (char*)sqlite3_value_text(pVal);
252530
+ *pbFreeAndReset = 0;
252462252531
}
252463252532
252464252533
return rc;
252465252534
}
252466252535
@@ -252996,23 +253065,18 @@
252996253065
252997253066
/* INSERT or UPDATE */
252998253067
else{
252999253068
int eType1 = sqlite3_value_numeric_type(apVal[1]);
253000253069
253001
- /* Ensure that no fts5_locale() values are written to locale=0 tables.
253002
- ** And that no blobs except fts5_locale() blobs are written to indexed
253003
- ** (i.e. not UNINDEXED) columns of locale=1 tables. */
253004
- int ii;
253005
- for(ii=0; ii<pConfig->nCol; ii++){
253006
- if( sqlite3_value_type(apVal[ii+2])==SQLITE_BLOB ){
253007
- int bSub = (sqlite3_value_subtype(apVal[ii+2])==FTS5_LOCALE_SUBTYPE);
253008
- if( (pConfig->bLocale && !bSub && pConfig->abUnindexed[ii]==0)
253009
- || (pConfig->bLocale==0 && bSub)
253010
- ){
253011
- if( pConfig->bLocale==0 ){
253012
- fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
253013
- }
253070
+ /* It is an error to write an fts5_locale() value to a table without
253071
+ ** the locale=1 option. */
253072
+ if( pConfig->bLocale==0 ){
253073
+ int ii;
253074
+ for(ii=0; ii<pConfig->nCol; ii++){
253075
+ sqlite3_value *pVal = apVal[ii+2];
253076
+ if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
253077
+ fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
253014253078
rc = SQLITE_MISMATCH;
253015253079
goto update_out;
253016253080
}
253017253081
}
253018253082
}
@@ -253169,15 +253233,15 @@
253169253233
){
253170253234
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253171253235
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
253172253236
int rc = SQLITE_OK;
253173253237
253174
- fts5SetLocale(pTab->pConfig, pLoc, nLoc);
253238
+ sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc);
253175253239
rc = sqlite3Fts5Tokenize(pTab->pConfig,
253176253240
FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
253177253241
);
253178
- fts5SetLocale(pTab->pConfig, 0, 0);
253242
+ sqlite3Fts5SetLocale(pTab->pConfig, 0, 0);
253179253243
253180253244
return rc;
253181253245
}
253182253246
253183253247
/*
@@ -253200,10 +253264,53 @@
253200253264
253201253265
static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
253202253266
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253203253267
return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
253204253268
}
253269
+
253270
+/*
253271
+** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This
253272
+** function extracts the text value of column iCol of the current row.
253273
+** Additionally, if there is an associated locale, it invokes
253274
+** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller
253275
+** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point
253276
+** after this function returns.
253277
+**
253278
+** If successful, (*ppText) is set to point to a buffer containing the text
253279
+** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that
253280
+** buffer in bytes. It is not guaranteed to be nul-terminated. If an error
253281
+** occurs, an SQLite error code is returned. The final values of the two
253282
+** output parameters are undefined in this case.
253283
+*/
253284
+static int fts5TextFromStmt(
253285
+ Fts5Config *pConfig,
253286
+ sqlite3_stmt *pStmt,
253287
+ int iCol,
253288
+ const char **ppText,
253289
+ int *pnText
253290
+){
253291
+ sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1);
253292
+ const char *pLoc = 0;
253293
+ int nLoc = 0;
253294
+ int rc = SQLITE_OK;
253295
+
253296
+ if( pConfig->bLocale
253297
+ && pConfig->eContent==FTS5_CONTENT_EXTERNAL
253298
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
253299
+ ){
253300
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc);
253301
+ }else{
253302
+ *ppText = (const char*)sqlite3_value_text(pVal);
253303
+ *pnText = sqlite3_value_bytes(pVal);
253304
+ if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){
253305
+ pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol);
253306
+ nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol);
253307
+ }
253308
+ }
253309
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
253310
+ return rc;
253311
+}
253205253312
253206253313
static int fts5ApiColumnText(
253207253314
Fts5Context *pCtx,
253208253315
int iCol,
253209253316
const char **pz,
@@ -253220,14 +253327,12 @@
253220253327
*pz = 0;
253221253328
*pn = 0;
253222253329
}else{
253223253330
rc = fts5SeekCursor(pCsr, 0);
253224253331
if( rc==SQLITE_OK ){
253225
- Fts5Config *pConfig = pTab->pConfig;
253226
- int bContent = (pConfig->abUnindexed[iCol]==0);
253227
- sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253228
- sqlite3Fts5ExtractText(pConfig, pVal, bContent, 0, pz, pn);
253332
+ rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn);
253333
+ sqlite3Fts5ClearLocale(pTab->pConfig);
253229253334
}
253230253335
}
253231253336
return rc;
253232253337
}
253233253338
@@ -253265,21 +253370,19 @@
253265253370
if( aPopulator==0 ) rc = SQLITE_NOMEM;
253266253371
if( rc==SQLITE_OK ){
253267253372
rc = fts5SeekCursor(pCsr, 0);
253268253373
}
253269253374
for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
253270
- sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253271253375
const char *z = 0;
253272253376
int n = 0;
253273
- int bReset = 0;
253274
- rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
253377
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
253275253378
if( rc==SQLITE_OK ){
253276253379
rc = sqlite3Fts5ExprPopulatePoslists(
253277253380
pConfig, pCsr->pExpr, aPopulator, i, z, n
253278253381
);
253279253382
}
253280
- if( bReset ) sqlite3Fts5ClearLocale(pConfig);
253383
+ sqlite3Fts5ClearLocale(pConfig);
253281253384
}
253282253385
sqlite3_free(aPopulator);
253283253386
253284253387
if( pCsr->pSorter ){
253285253388
sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
@@ -253461,21 +253564,18 @@
253461253564
rc = fts5SeekCursor(pCsr, 0);
253462253565
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
253463253566
if( pConfig->abUnindexed[i]==0 ){
253464253567
const char *z = 0;
253465253568
int n = 0;
253466
- int bReset = 0;
253467
- sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253468
-
253469253569
pCsr->aColumnSize[i] = 0;
253470
- rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
253570
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
253471253571
if( rc==SQLITE_OK ){
253472253572
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX,
253473253573
z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb
253474253574
);
253475
- if( bReset ) sqlite3Fts5ClearLocale(pConfig);
253476253575
}
253576
+ sqlite3Fts5ClearLocale(pConfig);
253477253577
}
253478253578
}
253479253579
}
253480253580
CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
253481253581
}
@@ -253743,41 +253843,18 @@
253743253843
&& pConfig->eContent!=FTS5_CONTENT_NONE
253744253844
&& pConfig->bLocale
253745253845
){
253746253846
rc = fts5SeekCursor(pCsr, 0);
253747253847
if( rc==SQLITE_OK ){
253748
- /* Load the value into pVal. pVal is a locale/text pair iff:
253749
- **
253750
- ** 1) It is an SQLITE_BLOB, and
253751
- ** 2) Either the subtype is FTS5_LOCALE_SUBTYPE, or else the
253752
- ** value was loaded from an FTS5_CONTENT_NORMAL table, and
253753
- ** 3) It does not begin with an 0x00 byte.
253754
- */
253755
- sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253756
- if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
253757
- const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
253758
- int nBlob = sqlite3_value_bytes(pVal);
253759
- if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
253760
- const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
253761
- if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
253762
- rc = SQLITE_ERROR;
253763
- }
253764
- pBlob += 4;
253765
- nBlob -= 4;
253766
- }
253767
- if( rc==SQLITE_OK ){
253768
- int nLocale = 0;
253769
- for(nLocale=0; nLocale<nBlob && pBlob[nLocale]!=0x00; nLocale++);
253770
- if( nLocale==nBlob || nLocale==0 ){
253771
- rc = SQLITE_ERROR;
253772
- }else{
253773
- /* A locale/text pair */
253774
- *pzLocale = (const char*)pBlob;
253775
- *pnLocale = nLocale;
253776
- }
253777
- }
253778
- }
253848
+ const char *zDummy = 0;
253849
+ int nDummy = 0;
253850
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy);
253851
+ if( rc==SQLITE_OK ){
253852
+ *pzLocale = pConfig->t.pLocale;
253853
+ *pnLocale = pConfig->t.nLocale;
253854
+ }
253855
+ sqlite3Fts5ClearLocale(pConfig);
253779253856
}
253780253857
}
253781253858
253782253859
return rc;
253783253860
}
@@ -253994,61 +254071,10 @@
253994254071
253995254072
sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
253996254073
return rc;
253997254074
}
253998254075
253999
-/*
254000
-** Value pVal was read from column iCol of the FTS5 table. This function
254001
-** returns it to the owner of pCtx via a call to an sqlite3_result_xxx()
254002
-** function. This function deals with the same cases as
254003
-** sqlite3Fts5ExtractText():
254004
-**
254005
-** 1) Ordinary values. These can be returned using sqlite3_result_value().
254006
-**
254007
-** 2) Blobs from fts5_locale(). The text is extracted from these and
254008
-** returned via sqlite3_result_text(). The locale is discarded.
254009
-*/
254010
-static void fts5ExtractValueFromColumn(
254011
- sqlite3_context *pCtx,
254012
- Fts5Config *pConfig,
254013
- int iCol,
254014
- sqlite3_value *pVal
254015
-){
254016
- assert( pConfig->eContent!=FTS5_CONTENT_NONE );
254017
-
254018
- if( pConfig->bLocale
254019
- && sqlite3_value_type(pVal)==SQLITE_BLOB
254020
- && pConfig->abUnindexed[iCol]==0
254021
- ){
254022
- const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
254023
- const u8 *pBlob = sqlite3_value_blob(pVal);
254024
- int nBlob = sqlite3_value_bytes(pVal);
254025
- int ii;
254026
-
254027
- if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
254028
- if( nBlob<SZHDR || memcmp(pBlob, FTS5_LOCALE_HEADER, SZHDR) ){
254029
- sqlite3_result_error_code(pCtx, SQLITE_ERROR);
254030
- return;
254031
- }else{
254032
- pBlob += 4;
254033
- nBlob -= 4;
254034
- }
254035
- }
254036
-
254037
- for(ii=0; ii<nBlob && pBlob[ii]; ii++);
254038
- if( ii==0 || ii==nBlob ){
254039
- sqlite3_result_error_code(pCtx, SQLITE_ERROR);
254040
- }else{
254041
- const char *pText = (const char*)&pBlob[ii+1];
254042
- sqlite3_result_text(pCtx, pText, nBlob-ii-1, SQLITE_TRANSIENT);
254043
- }
254044
- return;
254045
- }
254046
-
254047
- sqlite3_result_value(pCtx, pVal);
254048
-}
254049
-
254050254076
/*
254051254077
** This is the xColumn method, called by SQLite to request a value from
254052254078
** the row that the supplied cursor currently points to.
254053254079
*/
254054254080
static int fts5ColumnMethod(
@@ -254101,12 +254127,26 @@
254101254127
}else if( bNochange==0 || pConfig->eContent!=FTS5_CONTENT_NORMAL ){
254102254128
pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
254103254129
rc = fts5SeekCursor(pCsr, 1);
254104254130
if( rc==SQLITE_OK ){
254105254131
sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
254106
- fts5ExtractValueFromColumn(pCtx, pConfig, iCol, pVal);
254132
+ if( pConfig->bLocale
254133
+ && pConfig->eContent==FTS5_CONTENT_EXTERNAL
254134
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
254135
+ ){
254136
+ const char *z = 0;
254137
+ int n = 0;
254138
+ rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n);
254139
+ if( rc==SQLITE_OK ){
254140
+ sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT);
254141
+ }
254142
+ sqlite3Fts5ClearLocale(pConfig);
254143
+ }else{
254144
+ sqlite3_result_value(pCtx, pVal);
254145
+ }
254107254146
}
254147
+
254108254148
pConfig->pzErrmsg = 0;
254109254149
}
254110254150
}
254111254151
254112254152
return rc;
@@ -254625,11 +254665,11 @@
254625254665
int nArg, /* Number of args */
254626254666
sqlite3_value **apUnused /* Function arguments */
254627254667
){
254628254668
assert( nArg==0 );
254629254669
UNUSED_PARAM2(nArg, apUnused);
254630
- sqlite3_result_text(pCtx, "fts5: 2024-09-02 18:41:59 e6bec37ea1ca51e1d048941ce4c5211d8fc5c5e3556a1441f9c79b036843f9e3", -1, SQLITE_TRANSIENT);
254670
+ sqlite3_result_text(pCtx, "fts5: 2024-09-17 22:57:08 a63e412b6b2939422ecfa99d91fccb7a9c61e1533bb0db20ff12f3815ef41a2c", -1, SQLITE_TRANSIENT);
254631254671
}
254632254672
254633254673
/*
254634254674
** Implementation of fts5_locale(LOCALE, TEXT) function.
254635254675
**
@@ -254664,34 +254704,32 @@
254664254704
nText = sqlite3_value_bytes(apArg[1]);
254665254705
254666254706
if( zLocale==0 || zLocale[0]=='\0' ){
254667254707
sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
254668254708
}else{
254709
+ Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx);
254669254710
u8 *pBlob = 0;
254670254711
u8 *pCsr = 0;
254671254712
int nBlob = 0;
254672
- const int nHdr = 4;
254673
- assert( sizeof(FTS5_LOCALE_HEADER)==nHdr+1 );
254674254713
254675
- nBlob = nHdr + nLocale + 1 + nText;
254714
+ nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText;
254676254715
pBlob = (u8*)sqlite3_malloc(nBlob);
254677254716
if( pBlob==0 ){
254678254717
sqlite3_result_error_nomem(pCtx);
254679254718
return;
254680254719
}
254681254720
254682254721
pCsr = pBlob;
254683
- memcpy(pCsr, FTS5_LOCALE_HEADER, nHdr);
254684
- pCsr += nHdr;
254722
+ memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE);
254723
+ pCsr += FTS5_LOCALE_HDR_SIZE;
254685254724
memcpy(pCsr, zLocale, nLocale);
254686254725
pCsr += nLocale;
254687254726
(*pCsr++) = 0x00;
254688254727
if( zText ) memcpy(pCsr, zText, nText);
254689254728
assert( &pCsr[nText]==&pBlob[nBlob] );
254690254729
254691254730
sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
254692
- sqlite3_result_subtype(pCtx, FTS5_LOCALE_SUBTYPE);
254693254731
}
254694254732
}
254695254733
254696254734
/*
254697254735
** Return true if zName is the extension on one of the shadow tables used
@@ -254789,10 +254827,20 @@
254789254827
pGlobal->api.xCreateFunction = fts5CreateAux;
254790254828
pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
254791254829
pGlobal->api.xFindTokenizer = fts5FindTokenizer;
254792254830
pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
254793254831
pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
254832
+
254833
+ /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector.
254834
+ ** The constants below were generated randomly. */
254835
+ sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr);
254836
+ pGlobal->aLocaleHdr[0] ^= 0xF924976D;
254837
+ pGlobal->aLocaleHdr[1] ^= 0x16596E13;
254838
+ pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA;
254839
+ pGlobal->aLocaleHdr[3] ^= 0x9B03A67F;
254840
+ assert( sizeof(pGlobal->aLocaleHdr)==16 );
254841
+
254794254842
rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
254795254843
if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
254796254844
if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
254797254845
if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
254798254846
if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
@@ -254944,10 +254992,34 @@
254944254992
#define FTS5_STMT_REPLACE_DOCSIZE 7
254945254993
#define FTS5_STMT_DELETE_DOCSIZE 8
254946254994
#define FTS5_STMT_LOOKUP_DOCSIZE 9
254947254995
#define FTS5_STMT_REPLACE_CONFIG 10
254948254996
#define FTS5_STMT_SCAN 11
254997
+
254998
+/*
254999
+** Return a pointer to a buffer obtained from sqlite3_malloc() that contains
255000
+** nBind comma-separated question marks. e.g. if nBind is passed 5, this
255001
+** function returns "?,?,?,?,?".
255002
+**
255003
+** If *pRc is not SQLITE_OK when this function is called, it is a no-op and
255004
+** NULL is returned immediately. Or, if the attempt to malloc a buffer
255005
+** fails, then *pRc is set to SQLITE_NOMEM and NULL is returned. Otherwise,
255006
+** if it is SQLITE_OK when this function is called and the malloc() succeeds,
255007
+** *pRc is left unchanged.
255008
+*/
255009
+static char *fts5BindingsList(int *pRc, int nBind){
255010
+ char *zBind = sqlite3Fts5MallocZero(pRc, 1 + nBind*2);
255011
+ if( zBind ){
255012
+ int ii;
255013
+ for(ii=0; ii<nBind; ii++){
255014
+ zBind[ii*2] = '?';
255015
+ zBind[ii*2 + 1] = ',';
255016
+ }
255017
+ zBind[ii*2-1] = '\0';
255018
+ }
255019
+ return zBind;
255020
+}
254949255021
254950255022
/*
254951255023
** Prepare the two insert statements - Fts5Storage.pInsertContent and
254952255024
** Fts5Storage.pInsertDocsize - if they have not already been prepared.
254953255025
** Return SQLITE_OK if successful, or an SQLite error code if an error
@@ -255013,23 +255085,24 @@
255013255085
zSql = sqlite3_mprintf(azStmt[eStmt],
255014255086
pC->zContentExprlist, pC->zContent, pC->zContentRowid
255015255087
);
255016255088
break;
255017255089
255018
- case FTS5_STMT_INSERT_CONTENT:
255019
- case FTS5_STMT_REPLACE_CONTENT: {
255020
- int nCol = pC->nCol + 1;
255090
+ case FTS5_STMT_INSERT_CONTENT: {
255091
+ int nCol = 0;
255021255092
char *zBind;
255022255093
int i;
255023255094
255024
- zBind = sqlite3_malloc64(1 + nCol*2);
255025
- if( zBind ){
255026
- for(i=0; i<nCol; i++){
255027
- zBind[i*2] = '?';
255028
- zBind[i*2 + 1] = ',';
255095
+ nCol = 1 + pC->nCol;
255096
+ if( pC->bLocale ){
255097
+ for(i=0; i<pC->nCol; i++){
255098
+ if( pC->abUnindexed[i]==0 ) nCol++;
255029255099
}
255030
- zBind[i*2-1] = '\0';
255100
+ }
255101
+
255102
+ zBind = fts5BindingsList(&rc, nCol);
255103
+ if( zBind ){
255031255104
zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
255032255105
sqlite3_free(zBind);
255033255106
}
255034255107
break;
255035255108
}
@@ -255216,11 +255289,11 @@
255216255289
p->pIndex = pIndex;
255217255290
255218255291
if( bCreate ){
255219255292
if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
255220255293
int nDefn = 32 + pConfig->nCol*10;
255221
- char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
255294
+ char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20);
255222255295
if( zDefn==0 ){
255223255296
rc = SQLITE_NOMEM;
255224255297
}else{
255225255298
int i;
255226255299
int iOff;
@@ -255227,10 +255300,18 @@
255227255300
sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
255228255301
iOff = (int)strlen(zDefn);
255229255302
for(i=0; i<pConfig->nCol; i++){
255230255303
sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
255231255304
iOff += (int)strlen(&zDefn[iOff]);
255305
+ }
255306
+ if( pConfig->bLocale ){
255307
+ for(i=0; i<pConfig->nCol; i++){
255308
+ if( pConfig->abUnindexed[i]==0 ){
255309
+ sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i);
255310
+ iOff += (int)strlen(&zDefn[iOff]);
255311
+ }
255312
+ }
255232255313
}
255233255314
rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
255234255315
}
255235255316
sqlite3_free(zDefn);
255236255317
}
@@ -255379,33 +255460,43 @@
255379255460
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
255380255461
if( pConfig->abUnindexed[iCol-1]==0 ){
255381255462
sqlite3_value *pVal = 0;
255382255463
const char *pText = 0;
255383255464
int nText = 0;
255384
- int bReset = 0;
255465
+ const char *pLoc = 0;
255466
+ int nLoc = 0;
255385255467
255386255468
assert( pSeek==0 || apVal==0 );
255387255469
assert( pSeek!=0 || apVal!=0 );
255388255470
if( pSeek ){
255389255471
pVal = sqlite3_column_value(pSeek, iCol);
255390255472
}else{
255391255473
pVal = apVal[iCol-1];
255392255474
}
255393255475
255394
- rc = sqlite3Fts5ExtractText(
255395
- pConfig, pVal, pSeek!=0, &bReset, &pText, &nText
255396
- );
255476
+ if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
255477
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255478
+ }else{
255479
+ pText = (const char*)sqlite3_value_text(pVal);
255480
+ nText = sqlite3_value_bytes(pVal);
255481
+ if( pConfig->bLocale && pSeek ){
255482
+ pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol);
255483
+ nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol);
255484
+ }
255485
+ }
255486
+
255397255487
if( rc==SQLITE_OK ){
255488
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
255398255489
ctx.szCol = 0;
255399255490
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
255400255491
pText, nText, (void*)&ctx, fts5StorageInsertCallback
255401255492
);
255402255493
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
255403255494
if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){
255404255495
rc = FTS5_CORRUPT;
255405255496
}
255406
- if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255497
+ sqlite3Fts5ClearLocale(pConfig);
255407255498
}
255408255499
}
255409255500
}
255410255501
if( rc==SQLITE_OK && p->nTotalRow<1 ){
255411255502
rc = FTS5_CORRUPT;
@@ -255660,24 +255751,39 @@
255660255751
sqlite3Fts5BufferZero(&buf);
255661255752
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255662255753
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255663255754
ctx.szCol = 0;
255664255755
if( pConfig->abUnindexed[ctx.iCol]==0 ){
255665
- int bReset = 0; /* True if tokenizer locale must be reset */
255666255756
int nText = 0; /* Size of pText in bytes */
255667255757
const char *pText = 0; /* Pointer to buffer containing text value */
255758
+ int nLoc = 0; /* Size of pLoc in bytes */
255759
+ const char *pLoc = 0; /* Pointer to buffer containing text value */
255760
+
255668255761
sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1);
255762
+ if( pConfig->eContent==FTS5_CONTENT_EXTERNAL
255763
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
255764
+ ){
255765
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255766
+ }else{
255767
+ pText = (const char*)sqlite3_value_text(pVal);
255768
+ nText = sqlite3_value_bytes(pVal);
255769
+ if( pConfig->bLocale ){
255770
+ int iCol = ctx.iCol + 1 + pConfig->nCol;
255771
+ pLoc = (const char*)sqlite3_column_text(pScan, iCol);
255772
+ nLoc = sqlite3_column_bytes(pScan, iCol);
255773
+ }
255774
+ }
255669255775
255670
- rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &pText, &nText);
255671255776
if( rc==SQLITE_OK ){
255777
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
255672255778
rc = sqlite3Fts5Tokenize(pConfig,
255673255779
FTS5_TOKENIZE_DOCUMENT,
255674255780
pText, nText,
255675255781
(void*)&ctx,
255676255782
fts5StorageInsertCallback
255677255783
);
255678
- if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255784
+ sqlite3Fts5ClearLocale(pConfig);
255679255785
}
255680255786
}
255681255787
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255682255788
p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255683255789
}
@@ -255756,33 +255862,49 @@
255756255862
rc = fts5StorageNewRowid(p, piRowid);
255757255863
}
255758255864
}else{
255759255865
sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
255760255866
int i; /* Counter variable */
255867
+ int nIndexed = 0; /* Number indexed columns seen */
255761255868
rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
255762
- for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
255869
+ if( pInsert ) sqlite3_clear_bindings(pInsert);
255870
+
255871
+ /* Bind the rowid value */
255872
+ sqlite3_bind_value(pInsert, 1, apVal[1]);
255873
+
255874
+ /* Loop through values for user-defined columns. i=2 is the leftmost
255875
+ ** user-defined column. As is column 1 of pSavedRow. */
255876
+ for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
255877
+ int bUnindexed = pConfig->abUnindexed[i-2];
255763255878
sqlite3_value *pVal = apVal[i];
255879
+
255880
+ nIndexed += !bUnindexed;
255764255881
if( sqlite3_value_nochange(pVal) && p->pSavedRow ){
255765255882
/* This is an UPDATE statement, and column (i-2) was not modified.
255766255883
** Retrieve the value from Fts5Storage.pSavedRow instead. */
255767255884
pVal = sqlite3_column_value(p->pSavedRow, i-1);
255768
- }else if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE ){
255885
+ if( pConfig->bLocale && bUnindexed==0 ){
255886
+ sqlite3_bind_value(pInsert, pConfig->nCol + 1 + nIndexed,
255887
+ sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1)
255888
+ );
255889
+ }
255890
+ }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
255891
+ const char *pText = 0;
255892
+ const char *pLoc = 0;
255893
+ int nText = 0;
255894
+ int nLoc = 0;
255769255895
assert( pConfig->bLocale );
255770
- assert( i>1 );
255771
- if( pConfig->abUnindexed[i-2] ){
255772
- /* At attempt to insert an fts5_locale() value into an UNINDEXED
255773
- ** column. Strip the locale away and just bind the text. */
255774
- const char *pText = 0;
255775
- int nText = 0;
255776
- rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, 0, &pText, &nText);
255896
+
255897
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255898
+ if( rc==SQLITE_OK ){
255777255899
sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
255778
- }else{
255779
- const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
255780
- int nBlob = sqlite3_value_bytes(pVal);
255781
- assert( nBlob>4 );
255782
- sqlite3_bind_blob(pInsert, i, pBlob+4, nBlob-4, SQLITE_TRANSIENT);
255900
+ if( bUnindexed==0 ){
255901
+ int iLoc = pConfig->nCol + 1 + nIndexed;
255902
+ sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT);
255903
+ }
255783255904
}
255905
+
255784255906
continue;
255785255907
}
255786255908
255787255909
rc = sqlite3_bind_value(pInsert, i, pVal);
255788255910
}
@@ -255817,27 +255939,41 @@
255817255939
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255818255940
}
255819255941
for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255820255942
ctx.szCol = 0;
255821255943
if( pConfig->abUnindexed[ctx.iCol]==0 ){
255822
- int bReset = 0; /* True if tokenizer locale must be reset */
255823255944
int nText = 0; /* Size of pText in bytes */
255824255945
const char *pText = 0; /* Pointer to buffer containing text value */
255946
+ int nLoc = 0; /* Size of pText in bytes */
255947
+ const char *pLoc = 0; /* Pointer to buffer containing text value */
255948
+
255825255949
sqlite3_value *pVal = apVal[ctx.iCol+2];
255826
- int bDisk = 0;
255827255950
if( p->pSavedRow && sqlite3_value_nochange(pVal) ){
255828255951
pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1);
255829
- bDisk = 1;
255952
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){
255953
+ int iCol = ctx.iCol + 1 + pConfig->nCol;
255954
+ pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol);
255955
+ nLoc = sqlite3_column_bytes(p->pSavedRow, iCol);
255956
+ }
255957
+ }else{
255958
+ pVal = apVal[ctx.iCol+2];
255959
+ }
255960
+
255961
+ if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
255962
+ rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255963
+ }else{
255964
+ pText = (const char*)sqlite3_value_text(pVal);
255965
+ nText = sqlite3_value_bytes(pVal);
255830255966
}
255831
- rc = sqlite3Fts5ExtractText(pConfig, pVal, bDisk, &bReset, &pText,&nText);
255967
+
255832255968
if( rc==SQLITE_OK ){
255833
- assert( bReset==0 || pConfig->bLocale );
255969
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
255834255970
rc = sqlite3Fts5Tokenize(pConfig,
255835255971
FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx,
255836255972
fts5StorageInsertCallback
255837255973
);
255838
- if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255974
+ sqlite3Fts5ClearLocale(pConfig);
255839255975
}
255840255976
}
255841255977
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255842255978
p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255843255979
}
@@ -255998,41 +256134,65 @@
255998256134
}
255999256135
if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
256000256136
rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
256001256137
}
256002256138
for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
256003
- if( pConfig->abUnindexed[i] ) continue;
256004
- ctx.iCol = i;
256005
- ctx.szCol = 0;
256006
- if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256007
- rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
256008
- }
256009
- if( rc==SQLITE_OK ){
256010
- int bReset = 0; /* True if tokenizer locale must be reset */
256011
- int nText = 0; /* Size of pText in bytes */
256012
- const char *pText = 0; /* Pointer to buffer containing text value */
256013
-
256014
- rc = sqlite3Fts5ExtractText(pConfig,
256015
- sqlite3_column_value(pScan, i+1), 1, &bReset, &pText, &nText
256016
- );
256017
- if( rc==SQLITE_OK ){
256139
+ if( pConfig->abUnindexed[i]==0 ){
256140
+ const char *pText = 0;
256141
+ int nText = 0;
256142
+ const char *pLoc = 0;
256143
+ int nLoc = 0;
256144
+ sqlite3_value *pVal = sqlite3_column_value(pScan, i+1);
256145
+
256146
+ if( pConfig->eContent==FTS5_CONTENT_EXTERNAL
256147
+ && sqlite3Fts5IsLocaleValue(pConfig, pVal)
256148
+ ){
256149
+ rc = sqlite3Fts5DecodeLocaleValue(
256150
+ pVal, &pText, &nText, &pLoc, &nLoc
256151
+ );
256152
+ }else{
256153
+ if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){
256154
+ int iCol = i + 1 + pConfig->nCol;
256155
+ pLoc = (const char*)sqlite3_column_text(pScan, iCol);
256156
+ nLoc = sqlite3_column_bytes(pScan, iCol);
256157
+ }
256158
+ pText = (const char*)sqlite3_value_text(pVal);
256159
+ nText = sqlite3_value_bytes(pVal);
256160
+ }
256161
+
256162
+ ctx.iCol = i;
256163
+ ctx.szCol = 0;
256164
+
256165
+ if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256166
+ rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
256167
+ }
256168
+
256169
+ if( rc==SQLITE_OK ){
256170
+ sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
256018256171
rc = sqlite3Fts5Tokenize(pConfig,
256019256172
FTS5_TOKENIZE_DOCUMENT,
256020256173
pText, nText,
256021256174
(void*)&ctx,
256022256175
fts5StorageIntegrityCallback
256023256176
);
256024
- if( bReset ) sqlite3Fts5ClearLocale(pConfig);
256025
- }
256026
- }
256027
- if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
256028
- rc = FTS5_CORRUPT;
256029
- }
256030
- aTotalSize[i] += ctx.szCol;
256031
- if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256032
- sqlite3Fts5TermsetFree(ctx.pTermset);
256033
- ctx.pTermset = 0;
256177
+ sqlite3Fts5ClearLocale(pConfig);
256178
+ }
256179
+
256180
+ /* If this is not a columnsize=0 database, check that the number
256181
+ ** of tokens in the value matches the aColSize[] value read from
256182
+ ** the %_docsize table. */
256183
+ if( rc==SQLITE_OK
256184
+ && pConfig->bColumnsize
256185
+ && ctx.szCol!=aColSize[i]
256186
+ ){
256187
+ rc = FTS5_CORRUPT;
256188
+ }
256189
+ aTotalSize[i] += ctx.szCol;
256190
+ if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256191
+ sqlite3Fts5TermsetFree(ctx.pTermset);
256192
+ ctx.pTermset = 0;
256193
+ }
256034256194
}
256035256195
}
256036256196
sqlite3Fts5TermsetFree(ctx.pTermset);
256037256197
ctx.pTermset = 0;
256038256198
256039256199
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** 7891a266c4425722ae8b9231397ef9e42e24.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -462,11 +462,11 @@
462 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
463 ** [sqlite_version()] and [sqlite_source_id()].
464 */
465 #define SQLITE_VERSION "3.47.0"
466 #define SQLITE_VERSION_NUMBER 3047000
467 #define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
468
469 /*
470 ** CAPI3REF: Run-Time Library Version Numbers
471 ** KEYWORDS: sqlite3_version sqlite3_sourceid
472 **
@@ -29285,20 +29285,33 @@
29285
29286 #ifndef NDEBUG
29287 /*
29288 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
29289 ** intended for use inside assert() statements.
 
 
 
29290 */
29291 SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
 
 
 
 
 
29292 assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
29293 return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
29294 }
29295 SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
 
 
 
 
 
29296 assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
29297 return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
29298 }
29299 #endif
29300
29301 #endif /* !defined(SQLITE_MUTEX_OMIT) */
29302
29303 /************** End of mutex.c ***********************************************/
29304 /************** Begin file mutex_noop.c **************************************/
@@ -65171,11 +65184,11 @@
65171 ** 20: Salt-2, a different random integer changing with each ckpt
65172 ** 24: Checksum-1 (first part of checksum for first 24 bytes of header).
65173 ** 28: Checksum-2 (second part of checksum for first 24 bytes of header).
65174 **
65175 ** Immediately following the wal-header are zero or more frames. Each
65176 ** frame consists of a 24-byte frame-header followed by a <page-size> bytes
65177 ** of page data. The frame-header is six big-endian 32-bit unsigned
65178 ** integer values, as follows:
65179 **
65180 ** 0: Page number.
65181 ** 4: For commit records, the size of the database image in pages
@@ -92230,10 +92243,21 @@
92230 ** A successful evaluation of this routine acquires the mutex on p.
92231 ** the mutex is released if any kind of error occurs.
92232 **
92233 ** The error code stored in database p->db is overwritten with the return
92234 ** value in any case.
 
 
 
 
 
 
 
 
 
 
 
92235 */
92236 static int vdbeUnbind(Vdbe *p, unsigned int i){
92237 Mem *pVar;
92238 if( vdbeSafetyNotNull(p) ){
92239 return SQLITE_MISUSE_BKPT;
@@ -92287,10 +92311,11 @@
92287 Mem *pVar;
92288 int rc;
92289
92290 rc = vdbeUnbind(p, (u32)(i-1));
92291 if( rc==SQLITE_OK ){
 
92292 if( zData!=0 ){
92293 pVar = &p->aVar[i-1];
92294 rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
92295 if( rc==SQLITE_OK && encoding!=0 ){
92296 rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
@@ -92336,10 +92361,11 @@
92336 SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
92337 int rc;
92338 Vdbe *p = (Vdbe *)pStmt;
92339 rc = vdbeUnbind(p, (u32)(i-1));
92340 if( rc==SQLITE_OK ){
 
92341 sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
92342 sqlite3_mutex_leave(p->db->mutex);
92343 }
92344 return rc;
92345 }
@@ -92349,10 +92375,11 @@
92349 SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
92350 int rc;
92351 Vdbe *p = (Vdbe *)pStmt;
92352 rc = vdbeUnbind(p, (u32)(i-1));
92353 if( rc==SQLITE_OK ){
 
92354 sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
92355 sqlite3_mutex_leave(p->db->mutex);
92356 }
92357 return rc;
92358 }
@@ -92359,10 +92386,11 @@
92359 SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
92360 int rc;
92361 Vdbe *p = (Vdbe*)pStmt;
92362 rc = vdbeUnbind(p, (u32)(i-1));
92363 if( rc==SQLITE_OK ){
 
92364 sqlite3_mutex_leave(p->db->mutex);
92365 }
92366 return rc;
92367 }
92368 SQLITE_API int sqlite3_bind_pointer(
@@ -92374,10 +92402,11 @@
92374 ){
92375 int rc;
92376 Vdbe *p = (Vdbe*)pStmt;
92377 rc = vdbeUnbind(p, (u32)(i-1));
92378 if( rc==SQLITE_OK ){
 
92379 sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
92380 sqlite3_mutex_leave(p->db->mutex);
92381 }else if( xDestructor ){
92382 xDestructor(pPtr);
92383 }
@@ -92455,10 +92484,11 @@
92455 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
92456 int rc;
92457 Vdbe *p = (Vdbe *)pStmt;
92458 rc = vdbeUnbind(p, (u32)(i-1));
92459 if( rc==SQLITE_OK ){
 
92460 #ifndef SQLITE_OMIT_INCRBLOB
92461 sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
92462 #else
92463 rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
92464 #endif
@@ -169140,10 +169170,11 @@
169140 hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0;
169141 for(i=pWInfo->nLevel-1; i>=1; i--){
169142 WhereTerm *pTerm, *pEnd;
169143 SrcItem *pItem;
169144 WhereLoop *pLoop;
 
169145 pLoop = pWInfo->a[i].pWLoop;
169146 pItem = &pWInfo->pTabList->a[pLoop->iTab];
169147 if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
169148 if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0
169149 && (pLoop->wsFlags & WHERE_ONEROW)==0
@@ -169166,11 +169197,14 @@
169166 ){
169167 break; /* restriction (5) */
169168 }
169169 }
169170 if( pTerm<pEnd ) continue;
169171 WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId));
 
 
 
169172 notReady &= ~pLoop->maskSelf;
169173 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
169174 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
169175 pTerm->wtFlags |= TERM_CODED;
169176 }
@@ -208867,11 +208901,13 @@
208867 int rawKey = 1;
208868 x = pParse->aBlob[iRoot];
208869 zPath++;
208870 if( zPath[0]=='"' ){
208871 zKey = zPath + 1;
208872 for(i=1; zPath[i] && zPath[i]!='"'; i++){}
 
 
208873 nKey = i-1;
208874 if( zPath[i] ){
208875 i++;
208876 }else{
208877 return JSON_LOOKUP_PATHERROR;
@@ -219628,10 +219664,31 @@
219628 struct RbuFrame {
219629 u32 iDbPage;
219630 u32 iWalFrame;
219631 };
219632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219633 /*
219634 ** RBU handle.
219635 **
219636 ** nPhaseOneStep:
219637 ** If the RBU database contains an rbu_count table, this value is set to
@@ -219679,11 +219736,11 @@
219679 char *zState; /* Path to state db (or NULL if zRbu) */
219680 char zStateDb[5]; /* Db name for state ("stat" or "main") */
219681 int rc; /* Value returned by last rbu_step() call */
219682 char *zErrmsg; /* Error message if rc!=SQLITE_OK */
219683 int nStep; /* Rows processed for current object */
219684 int nProgress; /* Rows processed for all objects */
219685 RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
219686 const char *zVfsName; /* Name of automatically created rbu vfs */
219687 rbu_file *pTargetFd; /* File handle open on target db */
219688 int nPagePerSector; /* Pages per sector for pTargetFd */
219689 i64 iOalSz;
@@ -219796,11 +219853,11 @@
219796 unsigned char *zStart = z;
219797 while( (c = zValue[0x7f&*(z++)])>=0 ){
219798 v = (v<<6) + c;
219799 }
219800 z--;
219801 *pLen -= z - zStart;
219802 *pz = (char*)z;
219803 return v;
219804 }
219805
219806 #if RBU_ENABLE_DELTA_CKSUM
@@ -219981,10 +220038,11 @@
219981 int nOut;
219982 int nOut2;
219983 char *aOut;
219984
219985 assert( argc==2 );
 
219986
219987 nOrig = sqlite3_value_bytes(argv[0]);
219988 aOrig = (const char*)sqlite3_value_blob(argv[0]);
219989 nDelta = sqlite3_value_bytes(argv[1]);
219990 aDelta = (const char*)sqlite3_value_blob(argv[1]);
@@ -221560,17 +221618,17 @@
221560 nParen++;
221561 }
221562 else if( c==')' ){
221563 nParen--;
221564 if( nParen==0 ){
221565 int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
221566 pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
221567 i++;
221568 break;
221569 }
221570 }else if( c==',' && nParen==1 ){
221571 int nSpan = &zSql[i] - pIter->aIdxCol[iIdxCol].zSpan;
221572 pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
221573 pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
221574 }else if( c=='"' || c=='\'' || c=='`' ){
221575 for(i++; 1; i++){
221576 if( zSql[i]==c ){
@@ -222256,10 +222314,12 @@
222256 int i, sz;
222257 sz = (int)strlen(z)&0xffffff;
222258 for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
222259 if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
222260 }
 
 
222261 #endif
222262 }
222263
222264 /*
222265 ** Return the current wal-index header checksum for the target database
@@ -222840,11 +222900,11 @@
222840 "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES "
222841 "(%d, %d), "
222842 "(%d, %Q), "
222843 "(%d, %Q), "
222844 "(%d, %d), "
222845 "(%d, %d), "
222846 "(%d, %lld), "
222847 "(%d, %lld), "
222848 "(%d, %lld), "
222849 "(%d, %lld), "
222850 "(%d, %Q) ",
@@ -223198,10 +223258,11 @@
223198 char *zErrmsg = 0;
223199 int rc;
223200 sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
223201
223202 assert( nVal==1 );
 
223203
223204 rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
223205 sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
223206 "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
223207 );
@@ -223473,11 +223534,11 @@
223473 const char *zTarget,
223474 const char *zState
223475 ){
223476 if( zTarget==0 ){ return rbuMisuseError(); }
223477 if( zState ){
223478 int n = strlen(zState);
223479 if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
223480 return rbuMisuseError();
223481 }
223482 }
223483 /* TODO: Check that both arguments are non-NULL */
@@ -223690,10 +223751,11 @@
223690 /*
223691 ** Default xRename callback for RBU.
223692 */
223693 static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
223694 int rc = SQLITE_OK;
 
223695 #if defined(_WIN32_WCE)
223696 {
223697 LPWSTR zWideOld;
223698 LPWSTR zWideNew;
223699
@@ -224594,10 +224656,13 @@
224594
224595 /*
224596 ** No-op.
224597 */
224598 static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
 
 
 
224599 return 0;
224600 }
224601
224602 /*
224603 ** Deregister and destroy an RBU vfs created by an earlier call to
@@ -225650,11 +225715,17 @@
225650 ** schema for the database file that is to be read. The default schema is
225651 ** "main".
225652 **
225653 ** The data field of sqlite_dbpage table can be updated. The new
225654 ** value must be a BLOB which is the correct page size, otherwise the
225655 ** update fails. Rows may not be deleted or inserted.
 
 
 
 
 
 
225656 */
225657
225658 /* #include "sqliteInt.h" ** Requires access to internal data structures ** */
225659 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
225660 && !defined(SQLITE_OMIT_VIRTUALTABLE)
@@ -225673,17 +225744,18 @@
225673 };
225674
225675 struct DbpageTable {
225676 sqlite3_vtab base; /* Base class. Must be first */
225677 sqlite3 *db; /* The database */
 
 
225678 };
225679
225680 /* Columns */
225681 #define DBPAGE_COLUMN_PGNO 0
225682 #define DBPAGE_COLUMN_DATA 1
225683 #define DBPAGE_COLUMN_SCHEMA 2
225684
225685
225686
225687 /*
225688 ** Connect to or create a dbpagevfs virtual table.
225689 */
@@ -225722,10 +225794,12 @@
225722
225723 /*
225724 ** Disconnect from or destroy a dbpagevfs virtual table.
225725 */
225726 static int dbpageDisconnect(sqlite3_vtab *pVtab){
 
 
225727 sqlite3_free(pVtab);
225728 return SQLITE_OK;
225729 }
225730
225731 /*
@@ -225943,15 +226017,15 @@
225943 DbpageTable *pTab = (DbpageTable *)pVtab;
225944 Pgno pgno;
225945 DbPage *pDbPage = 0;
225946 int rc = SQLITE_OK;
225947 char *zErr = 0;
225948 const char *zSchema;
225949 int iDb;
225950 Btree *pBt;
225951 Pager *pPager;
225952 int szPage;
 
225953
225954 (void)pRowid;
225955 if( pTab->db->flags & SQLITE_Defensive ){
225956 zErr = "read-only";
225957 goto update_fail;
@@ -225958,44 +226032,65 @@
225958 }
225959 if( argc==1 ){
225960 zErr = "cannot delete";
225961 goto update_fail;
225962 }
225963 pgno = sqlite3_value_int(argv[0]);
225964 if( sqlite3_value_type(argv[0])==SQLITE_NULL
225965 || (Pgno)sqlite3_value_int(argv[1])!=pgno
225966 ){
225967 zErr = "cannot insert";
225968 goto update_fail;
225969 }
225970 zSchema = (const char*)sqlite3_value_text(argv[4]);
225971 iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1;
225972 if( NEVER(iDb<0) ){
225973 zErr = "no such schema";
225974 goto update_fail;
 
 
 
 
 
 
 
 
225975 }
225976 pBt = pTab->db->aDb[iDb].pBt;
225977 if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){
225978 zErr = "bad page number";
225979 goto update_fail;
225980 }
225981 szPage = sqlite3BtreeGetPageSize(pBt);
225982 if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
225983 || sqlite3_value_bytes(argv[3])!=szPage
225984 ){
225985 zErr = "bad page value";
225986 goto update_fail;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225987 }
225988 pPager = sqlite3BtreePager(pBt);
225989 rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
225990 if( rc==SQLITE_OK ){
225991 const void *pData = sqlite3_value_blob(argv[3]);
225992 assert( pData!=0 || pTab->db->mallocFailed );
225993 if( pData
225994 && (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK
225995 ){
225996 memcpy(sqlite3PagerGetData(pDbPage), pData, szPage);
225997 }
225998 }
225999 sqlite3PagerUnref(pDbPage);
226000 return rc;
226001
@@ -226014,10 +226109,30 @@
226014 sqlite3 *db = pTab->db;
226015 int i;
226016 for(i=0; i<db->nDb; i++){
226017 Btree *pBt = db->aDb[i].pBt;
226018 if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226019 }
226020 return SQLITE_OK;
226021 }
226022
226023
@@ -226039,11 +226154,11 @@
226039 dbpageEof, /* xEof - check for end of scan */
226040 dbpageColumn, /* xColumn - read data */
226041 dbpageRowid, /* xRowid - read data */
226042 dbpageUpdate, /* xUpdate */
226043 dbpageBegin, /* xBegin */
226044 0, /* xSync */
226045 0, /* xCommit */
226046 0, /* xRollback */
226047 0, /* xFindMethod */
226048 0, /* xRename */
226049 0, /* xSavepoint */
@@ -233972,20 +234087,17 @@
233972
233973 static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
233974
233975 static int sqlite3Fts5FlushToDisk(Fts5Table*);
233976
233977 static int sqlite3Fts5ExtractText(
233978 Fts5Config *pConfig,
233979 sqlite3_value *pVal, /* Value to extract text from */
233980 int bContent, /* Loaded from content table */
233981 int *pbResetTokenizer, /* OUT: True if ClearLocale() required */
233982 const char **ppText, /* OUT: Pointer to text buffer */
233983 int *pnText /* OUT: Size of (*ppText) in bytes */
233984 );
233985
233986 static void sqlite3Fts5ClearLocale(Fts5Config *pConfig);
 
 
 
 
 
 
233987
233988 /*
233989 ** End of interface to code in fts5.c.
233990 **************************************************************************/
233991
@@ -237544,10 +237656,19 @@
237544 sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
237545 }else{
237546 sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
237547 }
237548 }
 
 
 
 
 
 
 
 
 
237549 }
237550
237551 assert( p->zContentExprlist==0 );
237552 p->zContentExprlist = (char*)buf.p;
237553 return rc;
@@ -251113,11 +251234,20 @@
251113 i64 iNextId; /* Used to allocate unique cursor ids */
251114 Fts5Auxiliary *pAux; /* First in list of all aux. functions */
251115 Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
251116 Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
251117 Fts5Cursor *pCsr; /* First in list of all open cursors */
 
251118 };
 
 
 
 
 
 
 
 
251119
251120 /*
251121 ** Each auxiliary function registered with the FTS5 module is represented
251122 ** by an object of the following type. All such objects are stored as part
251123 ** of the Fts5Global.pAux list.
@@ -251277,16 +251407,10 @@
251277 #define FTS5CSR_REQUIRE_POSLIST 0x40
251278
251279 #define BitFlagAllTest(x,y) (((x) & (y))==(y))
251280 #define BitFlagTest(x,y) (((x) & (y))!=0)
251281
251282 /*
251283 ** The subtype value and header bytes used by fts5_locale().
251284 */
251285 #define FTS5_LOCALE_SUBTYPE ((unsigned int)'L')
251286 #define FTS5_LOCALE_HEADER "\x00\xE0\xB2\xEB"
251287
251288
251289 /*
251290 ** Macros to Set(), Clear() and Test() cursor flags.
251291 */
251292 #define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
@@ -252286,11 +252410,11 @@
252286 ** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale
252287 ** specified by pLocale/nLocale. The buffer indicated by pLocale must remain
252288 ** valid until after the final call to sqlite3Fts5Tokenize() that will use
252289 ** the locale.
252290 */
252291 static void fts5SetLocale(
252292 Fts5Config *pConfig,
252293 const char *zLocale,
252294 int nLocale
252295 ){
252296 Fts5TokenizerConfig *pT = &pConfig->t;
@@ -252297,141 +252421,88 @@
252297 pT->pLocale = zLocale;
252298 pT->nLocale = nLocale;
252299 }
252300
252301 /*
252302 ** Clear any locale configured by an earlier call to fts5SetLocale() or
252303 ** sqlite3Fts5ExtractText().
252304 */
252305 static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
252306 fts5SetLocale(pConfig, 0, 0);
252307 }
252308
252309 /*
252310 ** This function is used to extract utf-8 text from an sqlite3_value. This
252311 ** is usually done in order to tokenize it. For example, when:
252312 **
252313 ** * a value is written to an fts5 table,
252314 ** * a value is deleted from an FTS5_CONTENT_NORMAL table,
252315 ** * a value containing a query expression is passed to xFilter()
252316 **
252317 ** and so on.
252318 **
252319 ** This function handles 2 cases:
252320 **
252321 ** 1) Ordinary values. The text can be extracted from these using
252322 ** sqlite3_value_text().
252323 **
252324 ** 2) Combination text/locale blobs created by fts5_locale(). There
252325 ** are several cases for these:
252326 **
252327 ** * Blobs tagged with FTS5_LOCALE_SUBTYPE.
252328 ** * Blobs read from the content table of a locale=1 external-content
252329 ** table, and
252330 ** * Blobs read from the content table of a locale=1 regular
252331 ** content table.
252332 **
252333 ** The first two cases above should have the 4 byte FTS5_LOCALE_HEADER
252334 ** header. It is an error if a blob with the subtype or a blob read
252335 ** from the content table of an external content table does not have
252336 ** the required header. A blob read from the content table of a regular
252337 ** locale=1 table does not have the header. This is to save space.
252338 **
252339 ** If successful, SQLITE_OK is returned and output parameters (*ppText)
252340 ** and (*pnText) are set to point to a buffer containing the extracted utf-8
252341 ** text and its length in bytes, respectively. The buffer is not
252342 ** nul-terminated. It has the same lifetime as the sqlite3_value object
252343 ** from which it is extracted.
252344 **
252345 ** Parameter bContent must be true if the value was read from an indexed
252346 ** column (i.e. not UNINDEXED) of the on disk content.
252347 **
252348 ** If pbResetTokenizer is not NULL and if case (2) is used, then
252349 ** fts5SetLocale() is called to ensure subsequent sqlite3Fts5Tokenize() calls
252350 ** use the locale. In this case (*pbResetTokenizer) is set to true before
252351 ** returning, to indicate that the caller must call sqlite3Fts5ClearLocale()
252352 ** to clear the locale after tokenizing the text.
252353 */
252354 static int sqlite3Fts5ExtractText(
252355 Fts5Config *pConfig,
252356 sqlite3_value *pVal, /* Value to extract text from */
252357 int bContent, /* True if indexed table content */
252358 int *pbResetTokenizer, /* OUT: True if xSetLocale(NULL) required */
252359 const char **ppText, /* OUT: Pointer to text buffer */
252360 int *pnText /* OUT: Size of (*ppText) in bytes */
252361 ){
252362 const char *pText = 0;
252363 int nText = 0;
252364 int rc = SQLITE_OK;
252365 int bDecodeBlob = 0;
252366
252367 assert( pbResetTokenizer==0 || *pbResetTokenizer==0 );
252368 assert( bContent==0 || pConfig->eContent!=FTS5_CONTENT_NONE );
252369 assert( bContent==0 || sqlite3_value_subtype(pVal)==0 );
252370
252371 if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
252372 if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE
252373 || (bContent && pConfig->bLocale)
252374 ){
252375 bDecodeBlob = 1;
252376 }
252377 }
252378
252379 if( bDecodeBlob ){
252380 const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
252381 const u8 *pBlob = sqlite3_value_blob(pVal);
252382 int nBlob = sqlite3_value_bytes(pVal);
252383
252384 /* Unless this blob was read from the %_content table of an
252385 ** FTS5_CONTENT_NORMAL table, it should have the 4 byte fts5_locale()
252386 ** header. Check for this. If it is not found, return an error. */
252387 if( (!bContent || pConfig->eContent!=FTS5_CONTENT_NORMAL) ){
252388 if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
252389 rc = SQLITE_ERROR;
252390 }else{
252391 pBlob += 4;
252392 nBlob -= 4;
252393 }
252394 }
252395
252396 if( rc==SQLITE_OK ){
252397 int nLocale = 0;
252398
252399 for(nLocale=0; nLocale<nBlob; nLocale++){
252400 if( pBlob[nLocale]==0x00 ) break;
252401 }
252402 if( nLocale==nBlob || nLocale==0 ){
252403 rc = SQLITE_ERROR;
252404 }else{
252405 pText = (const char*)&pBlob[nLocale+1];
252406 nText = nBlob-nLocale-1;
252407
252408 if( pbResetTokenizer ){
252409 fts5SetLocale(pConfig, (const char*)pBlob, nLocale);
252410 *pbResetTokenizer = 1;
252411 }
252412 }
252413 }
252414
252415 }else{
252416 pText = (const char*)sqlite3_value_text(pVal);
252417 nText = sqlite3_value_bytes(pVal);
252418 }
252419
252420 *ppText = pText;
252421 *pnText = nText;
252422 return rc;
 
 
 
 
 
 
 
252423 }
252424
252425 /*
252426 ** Argument pVal is the text of a full-text search expression. It may or
252427 ** may not have been wrapped by fts5_locale(). This function extracts
252428 ** the text of the expression, and sets output variable (*pzText) to
252429 ** point to a nul-terminated buffer containing the expression.
252430 **
252431 ** If pVal was an fts5_locale() value, then fts5SetLocale() is called to
252432 ** set the tokenizer to use the specified locale.
252433 **
252434 ** If output variable (*pbFreeAndReset) is set to true, then the caller
252435 ** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
252436 ** locale, and (b) call sqlite3_free() to free (*pzText).
252437 */
@@ -252439,28 +252510,26 @@
252439 Fts5Config *pConfig, /* Fts5 configuration */
252440 sqlite3_value *pVal, /* Value to extract expression text from */
252441 char **pzText, /* OUT: nul-terminated buffer of text */
252442 int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */
252443 ){
252444 const char *zText = 0;
252445 int nText = 0;
252446 int rc = SQLITE_OK;
252447 int bReset = 0;
252448
252449 *pbFreeAndReset = 0;
252450 rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, &bReset, &zText, &nText);
252451 if( rc==SQLITE_OK ){
252452 if( bReset ){
252453 *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, zText);
252454 if( rc!=SQLITE_OK ){
252455 sqlite3Fts5ClearLocale(pConfig);
252456 }else{
252457 *pbFreeAndReset = 1;
252458 }
252459 }else{
252460 *pzText = (char*)zText;
252461 }
252462 }
252463
252464 return rc;
252465 }
252466
@@ -252996,23 +253065,18 @@
252996
252997 /* INSERT or UPDATE */
252998 else{
252999 int eType1 = sqlite3_value_numeric_type(apVal[1]);
253000
253001 /* Ensure that no fts5_locale() values are written to locale=0 tables.
253002 ** And that no blobs except fts5_locale() blobs are written to indexed
253003 ** (i.e. not UNINDEXED) columns of locale=1 tables. */
253004 int ii;
253005 for(ii=0; ii<pConfig->nCol; ii++){
253006 if( sqlite3_value_type(apVal[ii+2])==SQLITE_BLOB ){
253007 int bSub = (sqlite3_value_subtype(apVal[ii+2])==FTS5_LOCALE_SUBTYPE);
253008 if( (pConfig->bLocale && !bSub && pConfig->abUnindexed[ii]==0)
253009 || (pConfig->bLocale==0 && bSub)
253010 ){
253011 if( pConfig->bLocale==0 ){
253012 fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
253013 }
253014 rc = SQLITE_MISMATCH;
253015 goto update_out;
253016 }
253017 }
253018 }
@@ -253169,15 +253233,15 @@
253169 ){
253170 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253171 Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
253172 int rc = SQLITE_OK;
253173
253174 fts5SetLocale(pTab->pConfig, pLoc, nLoc);
253175 rc = sqlite3Fts5Tokenize(pTab->pConfig,
253176 FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
253177 );
253178 fts5SetLocale(pTab->pConfig, 0, 0);
253179
253180 return rc;
253181 }
253182
253183 /*
@@ -253200,10 +253264,53 @@
253200
253201 static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
253202 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253203 return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
253204 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253205
253206 static int fts5ApiColumnText(
253207 Fts5Context *pCtx,
253208 int iCol,
253209 const char **pz,
@@ -253220,14 +253327,12 @@
253220 *pz = 0;
253221 *pn = 0;
253222 }else{
253223 rc = fts5SeekCursor(pCsr, 0);
253224 if( rc==SQLITE_OK ){
253225 Fts5Config *pConfig = pTab->pConfig;
253226 int bContent = (pConfig->abUnindexed[iCol]==0);
253227 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253228 sqlite3Fts5ExtractText(pConfig, pVal, bContent, 0, pz, pn);
253229 }
253230 }
253231 return rc;
253232 }
253233
@@ -253265,21 +253370,19 @@
253265 if( aPopulator==0 ) rc = SQLITE_NOMEM;
253266 if( rc==SQLITE_OK ){
253267 rc = fts5SeekCursor(pCsr, 0);
253268 }
253269 for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
253270 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253271 const char *z = 0;
253272 int n = 0;
253273 int bReset = 0;
253274 rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
253275 if( rc==SQLITE_OK ){
253276 rc = sqlite3Fts5ExprPopulatePoslists(
253277 pConfig, pCsr->pExpr, aPopulator, i, z, n
253278 );
253279 }
253280 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
253281 }
253282 sqlite3_free(aPopulator);
253283
253284 if( pCsr->pSorter ){
253285 sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
@@ -253461,21 +253564,18 @@
253461 rc = fts5SeekCursor(pCsr, 0);
253462 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
253463 if( pConfig->abUnindexed[i]==0 ){
253464 const char *z = 0;
253465 int n = 0;
253466 int bReset = 0;
253467 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, i+1);
253468
253469 pCsr->aColumnSize[i] = 0;
253470 rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &z, &n);
253471 if( rc==SQLITE_OK ){
253472 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX,
253473 z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb
253474 );
253475 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
253476 }
 
253477 }
253478 }
253479 }
253480 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
253481 }
@@ -253743,41 +253843,18 @@
253743 && pConfig->eContent!=FTS5_CONTENT_NONE
253744 && pConfig->bLocale
253745 ){
253746 rc = fts5SeekCursor(pCsr, 0);
253747 if( rc==SQLITE_OK ){
253748 /* Load the value into pVal. pVal is a locale/text pair iff:
253749 **
253750 ** 1) It is an SQLITE_BLOB, and
253751 ** 2) Either the subtype is FTS5_LOCALE_SUBTYPE, or else the
253752 ** value was loaded from an FTS5_CONTENT_NORMAL table, and
253753 ** 3) It does not begin with an 0x00 byte.
253754 */
253755 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
253756 if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
253757 const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
253758 int nBlob = sqlite3_value_bytes(pVal);
253759 if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
253760 const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
253761 if( nBlob<SZHDR || memcmp(FTS5_LOCALE_HEADER, pBlob, SZHDR) ){
253762 rc = SQLITE_ERROR;
253763 }
253764 pBlob += 4;
253765 nBlob -= 4;
253766 }
253767 if( rc==SQLITE_OK ){
253768 int nLocale = 0;
253769 for(nLocale=0; nLocale<nBlob && pBlob[nLocale]!=0x00; nLocale++);
253770 if( nLocale==nBlob || nLocale==0 ){
253771 rc = SQLITE_ERROR;
253772 }else{
253773 /* A locale/text pair */
253774 *pzLocale = (const char*)pBlob;
253775 *pnLocale = nLocale;
253776 }
253777 }
253778 }
253779 }
253780 }
253781
253782 return rc;
253783 }
@@ -253994,61 +254071,10 @@
253994
253995 sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
253996 return rc;
253997 }
253998
253999 /*
254000 ** Value pVal was read from column iCol of the FTS5 table. This function
254001 ** returns it to the owner of pCtx via a call to an sqlite3_result_xxx()
254002 ** function. This function deals with the same cases as
254003 ** sqlite3Fts5ExtractText():
254004 **
254005 ** 1) Ordinary values. These can be returned using sqlite3_result_value().
254006 **
254007 ** 2) Blobs from fts5_locale(). The text is extracted from these and
254008 ** returned via sqlite3_result_text(). The locale is discarded.
254009 */
254010 static void fts5ExtractValueFromColumn(
254011 sqlite3_context *pCtx,
254012 Fts5Config *pConfig,
254013 int iCol,
254014 sqlite3_value *pVal
254015 ){
254016 assert( pConfig->eContent!=FTS5_CONTENT_NONE );
254017
254018 if( pConfig->bLocale
254019 && sqlite3_value_type(pVal)==SQLITE_BLOB
254020 && pConfig->abUnindexed[iCol]==0
254021 ){
254022 const int SZHDR = sizeof(FTS5_LOCALE_HEADER)-1;
254023 const u8 *pBlob = sqlite3_value_blob(pVal);
254024 int nBlob = sqlite3_value_bytes(pVal);
254025 int ii;
254026
254027 if( pConfig->eContent==FTS5_CONTENT_EXTERNAL ){
254028 if( nBlob<SZHDR || memcmp(pBlob, FTS5_LOCALE_HEADER, SZHDR) ){
254029 sqlite3_result_error_code(pCtx, SQLITE_ERROR);
254030 return;
254031 }else{
254032 pBlob += 4;
254033 nBlob -= 4;
254034 }
254035 }
254036
254037 for(ii=0; ii<nBlob && pBlob[ii]; ii++);
254038 if( ii==0 || ii==nBlob ){
254039 sqlite3_result_error_code(pCtx, SQLITE_ERROR);
254040 }else{
254041 const char *pText = (const char*)&pBlob[ii+1];
254042 sqlite3_result_text(pCtx, pText, nBlob-ii-1, SQLITE_TRANSIENT);
254043 }
254044 return;
254045 }
254046
254047 sqlite3_result_value(pCtx, pVal);
254048 }
254049
254050 /*
254051 ** This is the xColumn method, called by SQLite to request a value from
254052 ** the row that the supplied cursor currently points to.
254053 */
254054 static int fts5ColumnMethod(
@@ -254101,12 +254127,26 @@
254101 }else if( bNochange==0 || pConfig->eContent!=FTS5_CONTENT_NORMAL ){
254102 pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
254103 rc = fts5SeekCursor(pCsr, 1);
254104 if( rc==SQLITE_OK ){
254105 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
254106 fts5ExtractValueFromColumn(pCtx, pConfig, iCol, pVal);
 
 
 
 
 
 
 
 
 
 
 
 
 
254107 }
 
254108 pConfig->pzErrmsg = 0;
254109 }
254110 }
254111
254112 return rc;
@@ -254625,11 +254665,11 @@
254625 int nArg, /* Number of args */
254626 sqlite3_value **apUnused /* Function arguments */
254627 ){
254628 assert( nArg==0 );
254629 UNUSED_PARAM2(nArg, apUnused);
254630 sqlite3_result_text(pCtx, "fts5: 2024-09-02 18:41:59 e6bec37ea1ca51e1d048941ce4c5211d8fc5c5e3556a1441f9c79b036843f9e3", -1, SQLITE_TRANSIENT);
254631 }
254632
254633 /*
254634 ** Implementation of fts5_locale(LOCALE, TEXT) function.
254635 **
@@ -254664,34 +254704,32 @@
254664 nText = sqlite3_value_bytes(apArg[1]);
254665
254666 if( zLocale==0 || zLocale[0]=='\0' ){
254667 sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
254668 }else{
 
254669 u8 *pBlob = 0;
254670 u8 *pCsr = 0;
254671 int nBlob = 0;
254672 const int nHdr = 4;
254673 assert( sizeof(FTS5_LOCALE_HEADER)==nHdr+1 );
254674
254675 nBlob = nHdr + nLocale + 1 + nText;
254676 pBlob = (u8*)sqlite3_malloc(nBlob);
254677 if( pBlob==0 ){
254678 sqlite3_result_error_nomem(pCtx);
254679 return;
254680 }
254681
254682 pCsr = pBlob;
254683 memcpy(pCsr, FTS5_LOCALE_HEADER, nHdr);
254684 pCsr += nHdr;
254685 memcpy(pCsr, zLocale, nLocale);
254686 pCsr += nLocale;
254687 (*pCsr++) = 0x00;
254688 if( zText ) memcpy(pCsr, zText, nText);
254689 assert( &pCsr[nText]==&pBlob[nBlob] );
254690
254691 sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
254692 sqlite3_result_subtype(pCtx, FTS5_LOCALE_SUBTYPE);
254693 }
254694 }
254695
254696 /*
254697 ** Return true if zName is the extension on one of the shadow tables used
@@ -254789,10 +254827,20 @@
254789 pGlobal->api.xCreateFunction = fts5CreateAux;
254790 pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
254791 pGlobal->api.xFindTokenizer = fts5FindTokenizer;
254792 pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
254793 pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
 
 
 
 
 
 
 
 
 
 
254794 rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
254795 if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
254796 if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
254797 if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
254798 if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
@@ -254944,10 +254992,34 @@
254944 #define FTS5_STMT_REPLACE_DOCSIZE 7
254945 #define FTS5_STMT_DELETE_DOCSIZE 8
254946 #define FTS5_STMT_LOOKUP_DOCSIZE 9
254947 #define FTS5_STMT_REPLACE_CONFIG 10
254948 #define FTS5_STMT_SCAN 11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254949
254950 /*
254951 ** Prepare the two insert statements - Fts5Storage.pInsertContent and
254952 ** Fts5Storage.pInsertDocsize - if they have not already been prepared.
254953 ** Return SQLITE_OK if successful, or an SQLite error code if an error
@@ -255013,23 +255085,24 @@
255013 zSql = sqlite3_mprintf(azStmt[eStmt],
255014 pC->zContentExprlist, pC->zContent, pC->zContentRowid
255015 );
255016 break;
255017
255018 case FTS5_STMT_INSERT_CONTENT:
255019 case FTS5_STMT_REPLACE_CONTENT: {
255020 int nCol = pC->nCol + 1;
255021 char *zBind;
255022 int i;
255023
255024 zBind = sqlite3_malloc64(1 + nCol*2);
255025 if( zBind ){
255026 for(i=0; i<nCol; i++){
255027 zBind[i*2] = '?';
255028 zBind[i*2 + 1] = ',';
255029 }
255030 zBind[i*2-1] = '\0';
 
 
 
255031 zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
255032 sqlite3_free(zBind);
255033 }
255034 break;
255035 }
@@ -255216,11 +255289,11 @@
255216 p->pIndex = pIndex;
255217
255218 if( bCreate ){
255219 if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
255220 int nDefn = 32 + pConfig->nCol*10;
255221 char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10);
255222 if( zDefn==0 ){
255223 rc = SQLITE_NOMEM;
255224 }else{
255225 int i;
255226 int iOff;
@@ -255227,10 +255300,18 @@
255227 sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
255228 iOff = (int)strlen(zDefn);
255229 for(i=0; i<pConfig->nCol; i++){
255230 sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
255231 iOff += (int)strlen(&zDefn[iOff]);
 
 
 
 
 
 
 
 
255232 }
255233 rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
255234 }
255235 sqlite3_free(zDefn);
255236 }
@@ -255379,33 +255460,43 @@
255379 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
255380 if( pConfig->abUnindexed[iCol-1]==0 ){
255381 sqlite3_value *pVal = 0;
255382 const char *pText = 0;
255383 int nText = 0;
255384 int bReset = 0;
 
255385
255386 assert( pSeek==0 || apVal==0 );
255387 assert( pSeek!=0 || apVal!=0 );
255388 if( pSeek ){
255389 pVal = sqlite3_column_value(pSeek, iCol);
255390 }else{
255391 pVal = apVal[iCol-1];
255392 }
255393
255394 rc = sqlite3Fts5ExtractText(
255395 pConfig, pVal, pSeek!=0, &bReset, &pText, &nText
255396 );
 
 
 
 
 
 
 
 
255397 if( rc==SQLITE_OK ){
 
255398 ctx.szCol = 0;
255399 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
255400 pText, nText, (void*)&ctx, fts5StorageInsertCallback
255401 );
255402 p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
255403 if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){
255404 rc = FTS5_CORRUPT;
255405 }
255406 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255407 }
255408 }
255409 }
255410 if( rc==SQLITE_OK && p->nTotalRow<1 ){
255411 rc = FTS5_CORRUPT;
@@ -255660,24 +255751,39 @@
255660 sqlite3Fts5BufferZero(&buf);
255661 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255662 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255663 ctx.szCol = 0;
255664 if( pConfig->abUnindexed[ctx.iCol]==0 ){
255665 int bReset = 0; /* True if tokenizer locale must be reset */
255666 int nText = 0; /* Size of pText in bytes */
255667 const char *pText = 0; /* Pointer to buffer containing text value */
 
 
 
255668 sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1);
 
 
 
 
 
 
 
 
 
 
 
 
 
255669
255670 rc = sqlite3Fts5ExtractText(pConfig, pVal, 1, &bReset, &pText, &nText);
255671 if( rc==SQLITE_OK ){
 
255672 rc = sqlite3Fts5Tokenize(pConfig,
255673 FTS5_TOKENIZE_DOCUMENT,
255674 pText, nText,
255675 (void*)&ctx,
255676 fts5StorageInsertCallback
255677 );
255678 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255679 }
255680 }
255681 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255682 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255683 }
@@ -255756,33 +255862,49 @@
255756 rc = fts5StorageNewRowid(p, piRowid);
255757 }
255758 }else{
255759 sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
255760 int i; /* Counter variable */
 
255761 rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
255762 for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
 
 
 
 
 
 
 
 
255763 sqlite3_value *pVal = apVal[i];
 
 
255764 if( sqlite3_value_nochange(pVal) && p->pSavedRow ){
255765 /* This is an UPDATE statement, and column (i-2) was not modified.
255766 ** Retrieve the value from Fts5Storage.pSavedRow instead. */
255767 pVal = sqlite3_column_value(p->pSavedRow, i-1);
255768 }else if( sqlite3_value_subtype(pVal)==FTS5_LOCALE_SUBTYPE ){
 
 
 
 
 
 
 
 
 
255769 assert( pConfig->bLocale );
255770 assert( i>1 );
255771 if( pConfig->abUnindexed[i-2] ){
255772 /* At attempt to insert an fts5_locale() value into an UNINDEXED
255773 ** column. Strip the locale away and just bind the text. */
255774 const char *pText = 0;
255775 int nText = 0;
255776 rc = sqlite3Fts5ExtractText(pConfig, pVal, 0, 0, &pText, &nText);
255777 sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
255778 }else{
255779 const u8 *pBlob = (const u8*)sqlite3_value_blob(pVal);
255780 int nBlob = sqlite3_value_bytes(pVal);
255781 assert( nBlob>4 );
255782 sqlite3_bind_blob(pInsert, i, pBlob+4, nBlob-4, SQLITE_TRANSIENT);
255783 }
 
255784 continue;
255785 }
255786
255787 rc = sqlite3_bind_value(pInsert, i, pVal);
255788 }
@@ -255817,27 +255939,41 @@
255817 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255818 }
255819 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255820 ctx.szCol = 0;
255821 if( pConfig->abUnindexed[ctx.iCol]==0 ){
255822 int bReset = 0; /* True if tokenizer locale must be reset */
255823 int nText = 0; /* Size of pText in bytes */
255824 const char *pText = 0; /* Pointer to buffer containing text value */
 
 
 
255825 sqlite3_value *pVal = apVal[ctx.iCol+2];
255826 int bDisk = 0;
255827 if( p->pSavedRow && sqlite3_value_nochange(pVal) ){
255828 pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1);
255829 bDisk = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
255830 }
255831 rc = sqlite3Fts5ExtractText(pConfig, pVal, bDisk, &bReset, &pText,&nText);
255832 if( rc==SQLITE_OK ){
255833 assert( bReset==0 || pConfig->bLocale );
255834 rc = sqlite3Fts5Tokenize(pConfig,
255835 FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx,
255836 fts5StorageInsertCallback
255837 );
255838 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
255839 }
255840 }
255841 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255842 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255843 }
@@ -255998,41 +256134,65 @@
255998 }
255999 if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
256000 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
256001 }
256002 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
256003 if( pConfig->abUnindexed[i] ) continue;
256004 ctx.iCol = i;
256005 ctx.szCol = 0;
256006 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256007 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
256008 }
256009 if( rc==SQLITE_OK ){
256010 int bReset = 0; /* True if tokenizer locale must be reset */
256011 int nText = 0; /* Size of pText in bytes */
256012 const char *pText = 0; /* Pointer to buffer containing text value */
256013
256014 rc = sqlite3Fts5ExtractText(pConfig,
256015 sqlite3_column_value(pScan, i+1), 1, &bReset, &pText, &nText
256016 );
256017 if( rc==SQLITE_OK ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256018 rc = sqlite3Fts5Tokenize(pConfig,
256019 FTS5_TOKENIZE_DOCUMENT,
256020 pText, nText,
256021 (void*)&ctx,
256022 fts5StorageIntegrityCallback
256023 );
256024 if( bReset ) sqlite3Fts5ClearLocale(pConfig);
256025 }
256026 }
256027 if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){
256028 rc = FTS5_CORRUPT;
256029 }
256030 aTotalSize[i] += ctx.szCol;
256031 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256032 sqlite3Fts5TermsetFree(ctx.pTermset);
256033 ctx.pTermset = 0;
 
 
 
 
 
 
 
256034 }
256035 }
256036 sqlite3Fts5TermsetFree(ctx.pTermset);
256037 ctx.pTermset = 0;
256038
256039
--- extsrc/sqlite3.c
+++ extsrc/sqlite3.c
@@ -16,11 +16,11 @@
16 ** if you want a wrapper to interface SQLite with your choice of programming
17 ** language. The code for the "sqlite3" command-line shell is also in a
18 ** separate file. This file contains only code for the core SQLite library.
19 **
20 ** The content in this amalgamation comes from Fossil check-in
21 ** a63e412b6b2939422ecfa99d91fccb7a9c61.
22 */
23 #define SQLITE_CORE 1
24 #define SQLITE_AMALGAMATION 1
25 #ifndef SQLITE_PRIVATE
26 # define SQLITE_PRIVATE static
@@ -462,11 +462,11 @@
462 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
463 ** [sqlite_version()] and [sqlite_source_id()].
464 */
465 #define SQLITE_VERSION "3.47.0"
466 #define SQLITE_VERSION_NUMBER 3047000
467 #define SQLITE_SOURCE_ID "2024-09-17 22:57:08 a63e412b6b2939422ecfa99d91fccb7a9c61e1533bb0db20ff12f3815ef41a2c"
468
469 /*
470 ** CAPI3REF: Run-Time Library Version Numbers
471 ** KEYWORDS: sqlite3_version sqlite3_sourceid
472 **
@@ -29285,20 +29285,33 @@
29285
29286 #ifndef NDEBUG
29287 /*
29288 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
29289 ** intended for use inside assert() statements.
29290 **
29291 ** Because these routines raise false-positive alerts in TSAN, disable
29292 ** them (make them always return 1) when compiling with TSAN.
29293 */
29294 SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
29295 # if defined(__has_feature)
29296 # if __has_feature(thread_sanitizer)
29297 p = 0;
29298 # endif
29299 # endif
29300 assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
29301 return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
29302 }
29303 SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
29304 # if defined(__has_feature)
29305 # if __has_feature(thread_sanitizer)
29306 p = 0;
29307 # endif
29308 # endif
29309 assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
29310 return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
29311 }
29312 #endif /* NDEBUG */
29313
29314 #endif /* !defined(SQLITE_MUTEX_OMIT) */
29315
29316 /************** End of mutex.c ***********************************************/
29317 /************** Begin file mutex_noop.c **************************************/
@@ -65171,11 +65184,11 @@
65184 ** 20: Salt-2, a different random integer changing with each ckpt
65185 ** 24: Checksum-1 (first part of checksum for first 24 bytes of header).
65186 ** 28: Checksum-2 (second part of checksum for first 24 bytes of header).
65187 **
65188 ** Immediately following the wal-header are zero or more frames. Each
65189 ** frame consists of a 24-byte frame-header followed by <page-size> bytes
65190 ** of page data. The frame-header is six big-endian 32-bit unsigned
65191 ** integer values, as follows:
65192 **
65193 ** 0: Page number.
65194 ** 4: For commit records, the size of the database image in pages
@@ -92230,10 +92243,21 @@
92243 ** A successful evaluation of this routine acquires the mutex on p.
92244 ** the mutex is released if any kind of error occurs.
92245 **
92246 ** The error code stored in database p->db is overwritten with the return
92247 ** value in any case.
92248 **
92249 ** (tag-20240917-01) If vdbeUnbind(p,(u32)(i-1)) returns SQLITE_OK,
92250 ** that means all of the the following will be true:
92251 **
92252 ** p!=0
92253 ** p->pVar!=0
92254 ** i>0
92255 ** i<=p->nVar
92256 **
92257 ** An assert() is normally added after vdbeUnbind() to help static analyzers
92258 ** realize this.
92259 */
92260 static int vdbeUnbind(Vdbe *p, unsigned int i){
92261 Mem *pVar;
92262 if( vdbeSafetyNotNull(p) ){
92263 return SQLITE_MISUSE_BKPT;
@@ -92287,10 +92311,11 @@
92311 Mem *pVar;
92312 int rc;
92313
92314 rc = vdbeUnbind(p, (u32)(i-1));
92315 if( rc==SQLITE_OK ){
92316 assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
92317 if( zData!=0 ){
92318 pVar = &p->aVar[i-1];
92319 rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
92320 if( rc==SQLITE_OK && encoding!=0 ){
92321 rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
@@ -92336,10 +92361,11 @@
92361 SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
92362 int rc;
92363 Vdbe *p = (Vdbe *)pStmt;
92364 rc = vdbeUnbind(p, (u32)(i-1));
92365 if( rc==SQLITE_OK ){
92366 assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
92367 sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue);
92368 sqlite3_mutex_leave(p->db->mutex);
92369 }
92370 return rc;
92371 }
@@ -92349,10 +92375,11 @@
92375 SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
92376 int rc;
92377 Vdbe *p = (Vdbe *)pStmt;
92378 rc = vdbeUnbind(p, (u32)(i-1));
92379 if( rc==SQLITE_OK ){
92380 assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
92381 sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue);
92382 sqlite3_mutex_leave(p->db->mutex);
92383 }
92384 return rc;
92385 }
@@ -92359,10 +92386,11 @@
92386 SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
92387 int rc;
92388 Vdbe *p = (Vdbe*)pStmt;
92389 rc = vdbeUnbind(p, (u32)(i-1));
92390 if( rc==SQLITE_OK ){
92391 assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
92392 sqlite3_mutex_leave(p->db->mutex);
92393 }
92394 return rc;
92395 }
92396 SQLITE_API int sqlite3_bind_pointer(
@@ -92374,10 +92402,11 @@
92402 ){
92403 int rc;
92404 Vdbe *p = (Vdbe*)pStmt;
92405 rc = vdbeUnbind(p, (u32)(i-1));
92406 if( rc==SQLITE_OK ){
92407 assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
92408 sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
92409 sqlite3_mutex_leave(p->db->mutex);
92410 }else if( xDestructor ){
92411 xDestructor(pPtr);
92412 }
@@ -92455,10 +92484,11 @@
92484 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
92485 int rc;
92486 Vdbe *p = (Vdbe *)pStmt;
92487 rc = vdbeUnbind(p, (u32)(i-1));
92488 if( rc==SQLITE_OK ){
92489 assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
92490 #ifndef SQLITE_OMIT_INCRBLOB
92491 sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
92492 #else
92493 rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
92494 #endif
@@ -169140,10 +169170,11 @@
169170 hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0;
169171 for(i=pWInfo->nLevel-1; i>=1; i--){
169172 WhereTerm *pTerm, *pEnd;
169173 SrcItem *pItem;
169174 WhereLoop *pLoop;
169175 Bitmask m1;
169176 pLoop = pWInfo->a[i].pWLoop;
169177 pItem = &pWInfo->pTabList->a[pLoop->iTab];
169178 if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
169179 if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0
169180 && (pLoop->wsFlags & WHERE_ONEROW)==0
@@ -169166,11 +169197,14 @@
169197 ){
169198 break; /* restriction (5) */
169199 }
169200 }
169201 if( pTerm<pEnd ) continue;
169202 WHERETRACE(0xffffffff,("-> omit unused FROM-clause term %c\n",pLoop->cId));
169203 m1 = MASKBIT(i)-1;
169204 testcase( ((pWInfo->revMask>>1) & ~m1)!=0 );
169205 pWInfo->revMask = (m1 & pWInfo->revMask) | ((pWInfo->revMask>>1) & ~m1);
169206 notReady &= ~pLoop->maskSelf;
169207 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
169208 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
169209 pTerm->wtFlags |= TERM_CODED;
169210 }
@@ -208867,11 +208901,13 @@
208901 int rawKey = 1;
208902 x = pParse->aBlob[iRoot];
208903 zPath++;
208904 if( zPath[0]=='"' ){
208905 zKey = zPath + 1;
208906 for(i=1; zPath[i] && zPath[i]!='"'; i++){
208907 if( zPath[i]=='\\' && zPath[i+1]!=0 ) i++;
208908 }
208909 nKey = i-1;
208910 if( zPath[i] ){
208911 i++;
208912 }else{
208913 return JSON_LOOKUP_PATHERROR;
@@ -219628,10 +219664,31 @@
219664 struct RbuFrame {
219665 u32 iDbPage;
219666 u32 iWalFrame;
219667 };
219668
219669 #ifndef UNUSED_PARAMETER
219670 /*
219671 ** The following macros are used to suppress compiler warnings and to
219672 ** make it clear to human readers when a function parameter is deliberately
219673 ** left unused within the body of a function. This usually happens when
219674 ** a function is called via a function pointer. For example the
219675 ** implementation of an SQL aggregate step callback may not use the
219676 ** parameter indicating the number of arguments passed to the aggregate,
219677 ** if it knows that this is enforced elsewhere.
219678 **
219679 ** When a function parameter is not used at all within the body of a function,
219680 ** it is generally named "NotUsed" or "NotUsed2" to make things even clearer.
219681 ** However, these macros may also be used to suppress warnings related to
219682 ** parameters that may or may not be used depending on compilation options.
219683 ** For example those parameters only used in assert() statements. In these
219684 ** cases the parameters are named as per the usual conventions.
219685 */
219686 #define UNUSED_PARAMETER(x) (void)(x)
219687 #define UNUSED_PARAMETER2(x,y) UNUSED_PARAMETER(x),UNUSED_PARAMETER(y)
219688 #endif
219689
219690 /*
219691 ** RBU handle.
219692 **
219693 ** nPhaseOneStep:
219694 ** If the RBU database contains an rbu_count table, this value is set to
@@ -219679,11 +219736,11 @@
219736 char *zState; /* Path to state db (or NULL if zRbu) */
219737 char zStateDb[5]; /* Db name for state ("stat" or "main") */
219738 int rc; /* Value returned by last rbu_step() call */
219739 char *zErrmsg; /* Error message if rc!=SQLITE_OK */
219740 int nStep; /* Rows processed for current object */
219741 sqlite3_int64 nProgress; /* Rows processed for all objects */
219742 RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
219743 const char *zVfsName; /* Name of automatically created rbu vfs */
219744 rbu_file *pTargetFd; /* File handle open on target db */
219745 int nPagePerSector; /* Pages per sector for pTargetFd */
219746 i64 iOalSz;
@@ -219796,11 +219853,11 @@
219853 unsigned char *zStart = z;
219854 while( (c = zValue[0x7f&*(z++)])>=0 ){
219855 v = (v<<6) + c;
219856 }
219857 z--;
219858 *pLen -= (int)(z - zStart);
219859 *pz = (char*)z;
219860 return v;
219861 }
219862
219863 #if RBU_ENABLE_DELTA_CKSUM
@@ -219981,10 +220038,11 @@
220038 int nOut;
220039 int nOut2;
220040 char *aOut;
220041
220042 assert( argc==2 );
220043 UNUSED_PARAMETER(argc);
220044
220045 nOrig = sqlite3_value_bytes(argv[0]);
220046 aOrig = (const char*)sqlite3_value_blob(argv[0]);
220047 nDelta = sqlite3_value_bytes(argv[1]);
220048 aDelta = (const char*)sqlite3_value_blob(argv[1]);
@@ -221560,17 +221618,17 @@
221618 nParen++;
221619 }
221620 else if( c==')' ){
221621 nParen--;
221622 if( nParen==0 ){
221623 int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
221624 pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
221625 i++;
221626 break;
221627 }
221628 }else if( c==',' && nParen==1 ){
221629 int nSpan = (int)(&zSql[i] - pIter->aIdxCol[iIdxCol].zSpan);
221630 pIter->aIdxCol[iIdxCol++].nSpan = nSpan;
221631 pIter->aIdxCol[iIdxCol].zSpan = &zSql[i+1];
221632 }else if( c=='"' || c=='\'' || c=='`' ){
221633 for(i++; 1; i++){
221634 if( zSql[i]==c ){
@@ -222256,10 +222314,12 @@
222314 int i, sz;
222315 sz = (int)strlen(z)&0xffffff;
222316 for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
222317 if( z[i]=='.' && sz>i+4 ) memmove(&z[i+1], &z[sz-3], 4);
222318 }
222319 #else
222320 UNUSED_PARAMETER2(zBase,z);
222321 #endif
222322 }
222323
222324 /*
222325 ** Return the current wal-index header checksum for the target database
@@ -222840,11 +222900,11 @@
222900 "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES "
222901 "(%d, %d), "
222902 "(%d, %Q), "
222903 "(%d, %Q), "
222904 "(%d, %d), "
222905 "(%d, %lld), "
222906 "(%d, %lld), "
222907 "(%d, %lld), "
222908 "(%d, %lld), "
222909 "(%d, %lld), "
222910 "(%d, %Q) ",
@@ -223198,10 +223258,11 @@
223258 char *zErrmsg = 0;
223259 int rc;
223260 sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain);
223261
223262 assert( nVal==1 );
223263 UNUSED_PARAMETER(nVal);
223264
223265 rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg,
223266 sqlite3_mprintf("SELECT count(*) FROM sqlite_schema "
223267 "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0]))
223268 );
@@ -223473,11 +223534,11 @@
223534 const char *zTarget,
223535 const char *zState
223536 ){
223537 if( zTarget==0 ){ return rbuMisuseError(); }
223538 if( zState ){
223539 size_t n = strlen(zState);
223540 if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
223541 return rbuMisuseError();
223542 }
223543 }
223544 /* TODO: Check that both arguments are non-NULL */
@@ -223690,10 +223751,11 @@
223751 /*
223752 ** Default xRename callback for RBU.
223753 */
223754 static int xDefaultRename(void *pArg, const char *zOld, const char *zNew){
223755 int rc = SQLITE_OK;
223756 UNUSED_PARAMETER(pArg);
223757 #if defined(_WIN32_WCE)
223758 {
223759 LPWSTR zWideOld;
223760 LPWSTR zWideNew;
223761
@@ -224594,10 +224656,13 @@
224656
224657 /*
224658 ** No-op.
224659 */
224660 static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
224661 UNUSED_PARAMETER(pVfs);
224662 UNUSED_PARAMETER(a);
224663 UNUSED_PARAMETER(b);
224664 return 0;
224665 }
224666
224667 /*
224668 ** Deregister and destroy an RBU vfs created by an earlier call to
@@ -225650,11 +225715,17 @@
225715 ** schema for the database file that is to be read. The default schema is
225716 ** "main".
225717 **
225718 ** The data field of sqlite_dbpage table can be updated. The new
225719 ** value must be a BLOB which is the correct page size, otherwise the
225720 ** update fails. INSERT operations also work, and operate as if they
225721 ** where REPLACE. The size of the database can be extended by INSERT-ing
225722 ** new pages on the end.
225723 **
225724 ** Rows may not be deleted. However, doing an INSERT to page number N
225725 ** with NULL page data causes the N-th page and all subsequent pages to be
225726 ** deleted and the database to be truncated.
225727 */
225728
225729 /* #include "sqliteInt.h" ** Requires access to internal data structures ** */
225730 #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
225731 && !defined(SQLITE_OMIT_VIRTUALTABLE)
@@ -225673,17 +225744,18 @@
225744 };
225745
225746 struct DbpageTable {
225747 sqlite3_vtab base; /* Base class. Must be first */
225748 sqlite3 *db; /* The database */
225749 int nTrunc; /* Entries in aTrunc[] */
225750 Pgno *aTrunc; /* Truncation size for each database */
225751 };
225752
225753 /* Columns */
225754 #define DBPAGE_COLUMN_PGNO 0
225755 #define DBPAGE_COLUMN_DATA 1
225756 #define DBPAGE_COLUMN_SCHEMA 2
 
225757
225758
225759 /*
225760 ** Connect to or create a dbpagevfs virtual table.
225761 */
@@ -225722,10 +225794,12 @@
225794
225795 /*
225796 ** Disconnect from or destroy a dbpagevfs virtual table.
225797 */
225798 static int dbpageDisconnect(sqlite3_vtab *pVtab){
225799 DbpageTable *pTab = (DbpageTable *)pVtab;
225800 sqlite3_free(pTab->aTrunc);
225801 sqlite3_free(pVtab);
225802 return SQLITE_OK;
225803 }
225804
225805 /*
@@ -225943,15 +226017,15 @@
226017 DbpageTable *pTab = (DbpageTable *)pVtab;
226018 Pgno pgno;
226019 DbPage *pDbPage = 0;
226020 int rc = SQLITE_OK;
226021 char *zErr = 0;
 
226022 int iDb;
226023 Btree *pBt;
226024 Pager *pPager;
226025 int szPage;
226026 int isInsert;
226027
226028 (void)pRowid;
226029 if( pTab->db->flags & SQLITE_Defensive ){
226030 zErr = "read-only";
226031 goto update_fail;
@@ -225958,44 +226032,65 @@
226032 }
226033 if( argc==1 ){
226034 zErr = "cannot delete";
226035 goto update_fail;
226036 }
226037 if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
226038 pgno = (Pgno)sqlite3_value_int(argv[2]);
226039 isInsert = 1;
226040 }else{
226041 pgno = sqlite3_value_int(argv[0]);
226042 if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
226043 zErr = "cannot insert";
226044 goto update_fail;
226045 }
226046 isInsert = 0;
226047 }
226048 if( sqlite3_value_type(argv[4])==SQLITE_NULL ){
226049 iDb = 0;
226050 }else{
226051 const char *zSchema = (const char*)sqlite3_value_text(argv[4]);
226052 iDb = sqlite3FindDbName(pTab->db, zSchema);
226053 if( iDb<0 ){
226054 zErr = "no such schema";
226055 goto update_fail;
226056 }
226057 }
226058 pBt = pTab->db->aDb[iDb].pBt;
226059 if( pgno<1 || NEVER(pBt==0) ){
226060 zErr = "bad page number";
226061 goto update_fail;
226062 }
226063 szPage = sqlite3BtreeGetPageSize(pBt);
226064 if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
226065 || sqlite3_value_bytes(argv[3])!=szPage
226066 ){
226067 if( sqlite3_value_type(argv[3])==SQLITE_NULL && isInsert ){
226068 if( iDb>=pTab->nTrunc ){
226069 testcase( pTab->aTrunc!=0 );
226070 pTab->aTrunc = sqlite3_realloc(pTab->aTrunc, (iDb+1)*sizeof(Pgno));
226071 if( pTab->aTrunc ){
226072 int j;
226073 for(j=pTab->nTrunc; j<iDb; j++) pTab->aTrunc[j] = 0;
226074 pTab->nTrunc = iDb+1;
226075 }else{
226076 return SQLITE_NOMEM;
226077 }
226078 }
226079 pTab->aTrunc[iDb] = pgno;
226080 }else{
226081 zErr = "bad page value";
226082 goto update_fail;
226083 }
226084 }
226085 pPager = sqlite3BtreePager(pBt);
226086 rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
226087 if( rc==SQLITE_OK ){
226088 const void *pData = sqlite3_value_blob(argv[3]);
226089 if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
226090 unsigned char *aPage = sqlite3PagerGetData(pDbPage);
226091 memcpy(aPage, pData, szPage);
 
 
226092 }
226093 }
226094 sqlite3PagerUnref(pDbPage);
226095 return rc;
226096
@@ -226014,10 +226109,30 @@
226109 sqlite3 *db = pTab->db;
226110 int i;
226111 for(i=0; i<db->nDb; i++){
226112 Btree *pBt = db->aDb[i].pBt;
226113 if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
226114 }
226115 if( pTab->nTrunc>0 ){
226116 memset(pTab->aTrunc, 0, sizeof(pTab->aTrunc[0])*pTab->nTrunc);
226117 }
226118 return SQLITE_OK;
226119 }
226120
226121 /* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT
226122 */
226123 static int dbpageSync(sqlite3_vtab *pVtab){
226124 int iDb;
226125 DbpageTable *pTab = (DbpageTable *)pVtab;
226126
226127 for(iDb=0; iDb<pTab->nTrunc; iDb++){
226128 if( pTab->aTrunc[iDb]>0 ){
226129 Btree *pBt = pTab->db->aDb[iDb].pBt;
226130 Pager *pPager = sqlite3BtreePager(pBt);
226131 sqlite3PagerTruncateImage(pPager, pTab->aTrunc[iDb]);
226132 pTab->aTrunc[iDb] = 0;
226133 }
226134 }
226135 return SQLITE_OK;
226136 }
226137
226138
@@ -226039,11 +226154,11 @@
226154 dbpageEof, /* xEof - check for end of scan */
226155 dbpageColumn, /* xColumn - read data */
226156 dbpageRowid, /* xRowid - read data */
226157 dbpageUpdate, /* xUpdate */
226158 dbpageBegin, /* xBegin */
226159 dbpageSync, /* xSync */
226160 0, /* xCommit */
226161 0, /* xRollback */
226162 0, /* xFindMethod */
226163 0, /* xRename */
226164 0, /* xSavepoint */
@@ -233972,20 +234087,17 @@
234087
234088 static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64);
234089
234090 static int sqlite3Fts5FlushToDisk(Fts5Table*);
234091
 
 
 
 
 
 
 
 
 
234092 static void sqlite3Fts5ClearLocale(Fts5Config *pConfig);
234093 static void sqlite3Fts5SetLocale(Fts5Config *pConfig, const char *pLoc, int nLoc);
234094
234095 static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal);
234096 static int sqlite3Fts5DecodeLocaleValue(sqlite3_value *pVal,
234097 const char **ppText, int *pnText, const char **ppLoc, int *pnLoc
234098 );
234099
234100 /*
234101 ** End of interface to code in fts5.c.
234102 **************************************************************************/
234103
@@ -237544,10 +237656,19 @@
237656 sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]);
237657 }else{
237658 sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i);
237659 }
237660 }
237661 }
237662 if( p->eContent==FTS5_CONTENT_NORMAL && p->bLocale ){
237663 for(i=0; i<p->nCol; i++){
237664 if( p->abUnindexed[i]==0 ){
237665 sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.l%d", i);
237666 }else{
237667 sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", NULL");
237668 }
237669 }
237670 }
237671
237672 assert( p->zContentExprlist==0 );
237673 p->zContentExprlist = (char*)buf.p;
237674 return rc;
@@ -251113,11 +251234,20 @@
251234 i64 iNextId; /* Used to allocate unique cursor ids */
251235 Fts5Auxiliary *pAux; /* First in list of all aux. functions */
251236 Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */
251237 Fts5TokenizerModule *pDfltTok; /* Default tokenizer module */
251238 Fts5Cursor *pCsr; /* First in list of all open cursors */
251239 u32 aLocaleHdr[4];
251240 };
251241
251242 /*
251243 ** Size of header on fts5_locale() values. And macro to access a buffer
251244 ** containing a copy of the header from an Fts5Config pointer.
251245 */
251246 #define FTS5_LOCALE_HDR_SIZE ((int)sizeof( ((Fts5Global*)0)->aLocaleHdr ))
251247 #define FTS5_LOCALE_HDR(pConfig) ((const u8*)(pConfig->pGlobal->aLocaleHdr))
251248
251249
251250 /*
251251 ** Each auxiliary function registered with the FTS5 module is represented
251252 ** by an object of the following type. All such objects are stored as part
251253 ** of the Fts5Global.pAux list.
@@ -251277,16 +251407,10 @@
251407 #define FTS5CSR_REQUIRE_POSLIST 0x40
251408
251409 #define BitFlagAllTest(x,y) (((x) & (y))==(y))
251410 #define BitFlagTest(x,y) (((x) & (y))!=0)
251411
 
 
 
 
 
 
251412
251413 /*
251414 ** Macros to Set(), Clear() and Test() cursor flags.
251415 */
251416 #define CsrFlagSet(pCsr, flag) ((pCsr)->csrflags |= (flag))
@@ -252286,11 +252410,11 @@
252410 ** Arrange for subsequent calls to sqlite3Fts5Tokenize() to use the locale
252411 ** specified by pLocale/nLocale. The buffer indicated by pLocale must remain
252412 ** valid until after the final call to sqlite3Fts5Tokenize() that will use
252413 ** the locale.
252414 */
252415 static void sqlite3Fts5SetLocale(
252416 Fts5Config *pConfig,
252417 const char *zLocale,
252418 int nLocale
252419 ){
252420 Fts5TokenizerConfig *pT = &pConfig->t;
@@ -252297,141 +252421,88 @@
252421 pT->pLocale = zLocale;
252422 pT->nLocale = nLocale;
252423 }
252424
252425 /*
252426 ** Clear any locale configured by an earlier call to sqlite3Fts5SetLocale().
 
252427 */
252428 static void sqlite3Fts5ClearLocale(Fts5Config *pConfig){
252429 sqlite3Fts5SetLocale(pConfig, 0, 0);
252430 }
252431
252432 /*
252433 ** Return true if the value passed as the only argument is an
252434 ** fts5_locale() value.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252435 */
252436 static int sqlite3Fts5IsLocaleValue(Fts5Config *pConfig, sqlite3_value *pVal){
252437 int ret = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252438 if( sqlite3_value_type(pVal)==SQLITE_BLOB ){
252439 /* Call sqlite3_value_bytes() after sqlite3_value_blob() in this case.
252440 ** If the blob was created using zeroblob(), then sqlite3_value_blob()
252441 ** may call malloc(). If this malloc() fails, then the values returned
252442 ** by both value_blob() and value_bytes() will be 0. If value_bytes() were
252443 ** called first, then the NULL pointer returned by value_blob() might
252444 ** be dereferenced. */
 
 
 
252445 const u8 *pBlob = sqlite3_value_blob(pVal);
252446 int nBlob = sqlite3_value_bytes(pVal);
252447 if( nBlob>FTS5_LOCALE_HDR_SIZE
252448 && 0==memcmp(pBlob, FTS5_LOCALE_HDR(pConfig), FTS5_LOCALE_HDR_SIZE)
252449 ){
252450 ret = 1;
252451 }
252452 }
252453 return ret;
252454 }
252455
252456 /*
252457 ** Value pVal is guaranteed to be an fts5_locale() value, according to
252458 ** sqlite3Fts5IsLocaleValue(). This function extracts the text and locale
252459 ** from the value and returns them separately.
252460 **
252461 ** If successful, SQLITE_OK is returned and (*ppText) and (*ppLoc) set
252462 ** to point to buffers containing the text and locale, as utf-8,
252463 ** respectively. In this case output parameters (*pnText) and (*pnLoc) are
252464 ** set to the sizes in bytes of these two buffers.
252465 **
252466 ** Or, if an error occurs, then an SQLite error code is returned. The final
252467 ** value of the four output parameters is undefined in this case.
252468 */
252469 static int sqlite3Fts5DecodeLocaleValue(
252470 sqlite3_value *pVal,
252471 const char **ppText,
252472 int *pnText,
252473 const char **ppLoc,
252474 int *pnLoc
252475 ){
252476 const char *p = sqlite3_value_blob(pVal);
252477 int n = sqlite3_value_bytes(pVal);
252478 int nLoc = 0;
252479
252480 assert( sqlite3_value_type(pVal)==SQLITE_BLOB );
252481 assert( n>FTS5_LOCALE_HDR_SIZE );
252482
252483 for(nLoc=FTS5_LOCALE_HDR_SIZE; p[nLoc]; nLoc++){
252484 if( nLoc==(n-1) ){
252485 return SQLITE_MISMATCH;
252486 }
252487 }
252488 *ppLoc = &p[FTS5_LOCALE_HDR_SIZE];
252489 *pnLoc = nLoc - FTS5_LOCALE_HDR_SIZE;
252490
252491 *ppText = &p[nLoc+1];
252492 *pnText = n - nLoc - 1;
252493 return SQLITE_OK;
252494 }
252495
252496 /*
252497 ** Argument pVal is the text of a full-text search expression. It may or
252498 ** may not have been wrapped by fts5_locale(). This function extracts
252499 ** the text of the expression, and sets output variable (*pzText) to
252500 ** point to a nul-terminated buffer containing the expression.
252501 **
252502 ** If pVal was an fts5_locale() value, then sqlite3Fts5SetLocale() is called
252503 ** to set the tokenizer to use the specified locale.
252504 **
252505 ** If output variable (*pbFreeAndReset) is set to true, then the caller
252506 ** is required to (a) call sqlite3Fts5ClearLocale() to reset the tokenizer
252507 ** locale, and (b) call sqlite3_free() to free (*pzText).
252508 */
@@ -252439,28 +252510,26 @@
252510 Fts5Config *pConfig, /* Fts5 configuration */
252511 sqlite3_value *pVal, /* Value to extract expression text from */
252512 char **pzText, /* OUT: nul-terminated buffer of text */
252513 int *pbFreeAndReset /* OUT: Free (*pzText) and clear locale */
252514 ){
 
 
252515 int rc = SQLITE_OK;
252516
252517 if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
252518 const char *pText = 0;
252519 int nText = 0;
252520 const char *pLoc = 0;
252521 int nLoc = 0;
252522 rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
252523 *pzText = sqlite3Fts5Mprintf(&rc, "%.*s", nText, pText);
252524 if( rc==SQLITE_OK ){
252525 sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
252526 }
252527 *pbFreeAndReset = 1;
252528 }else{
252529 *pzText = (char*)sqlite3_value_text(pVal);
252530 *pbFreeAndReset = 0;
252531 }
252532
252533 return rc;
252534 }
252535
@@ -252996,23 +253065,18 @@
253065
253066 /* INSERT or UPDATE */
253067 else{
253068 int eType1 = sqlite3_value_numeric_type(apVal[1]);
253069
253070 /* It is an error to write an fts5_locale() value to a table without
253071 ** the locale=1 option. */
253072 if( pConfig->bLocale==0 ){
253073 int ii;
253074 for(ii=0; ii<pConfig->nCol; ii++){
253075 sqlite3_value *pVal = apVal[ii+2];
253076 if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
253077 fts5SetVtabError(pTab, "fts5_locale() requires locale=1");
 
 
 
 
 
253078 rc = SQLITE_MISMATCH;
253079 goto update_out;
253080 }
253081 }
253082 }
@@ -253169,15 +253233,15 @@
253233 ){
253234 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253235 Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
253236 int rc = SQLITE_OK;
253237
253238 sqlite3Fts5SetLocale(pTab->pConfig, pLoc, nLoc);
253239 rc = sqlite3Fts5Tokenize(pTab->pConfig,
253240 FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken
253241 );
253242 sqlite3Fts5SetLocale(pTab->pConfig, 0, 0);
253243
253244 return rc;
253245 }
253246
253247 /*
@@ -253200,10 +253264,53 @@
253264
253265 static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
253266 Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
253267 return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase);
253268 }
253269
253270 /*
253271 ** Argument pStmt is an SQL statement of the type used by Fts5Cursor. This
253272 ** function extracts the text value of column iCol of the current row.
253273 ** Additionally, if there is an associated locale, it invokes
253274 ** sqlite3Fts5SetLocale() to configure the tokenizer. In all cases the caller
253275 ** should invoke sqlite3Fts5ClearLocale() to clear the locale at some point
253276 ** after this function returns.
253277 **
253278 ** If successful, (*ppText) is set to point to a buffer containing the text
253279 ** value as utf-8 and SQLITE_OK returned. (*pnText) is set to the size of that
253280 ** buffer in bytes. It is not guaranteed to be nul-terminated. If an error
253281 ** occurs, an SQLite error code is returned. The final values of the two
253282 ** output parameters are undefined in this case.
253283 */
253284 static int fts5TextFromStmt(
253285 Fts5Config *pConfig,
253286 sqlite3_stmt *pStmt,
253287 int iCol,
253288 const char **ppText,
253289 int *pnText
253290 ){
253291 sqlite3_value *pVal = sqlite3_column_value(pStmt, iCol+1);
253292 const char *pLoc = 0;
253293 int nLoc = 0;
253294 int rc = SQLITE_OK;
253295
253296 if( pConfig->bLocale
253297 && pConfig->eContent==FTS5_CONTENT_EXTERNAL
253298 && sqlite3Fts5IsLocaleValue(pConfig, pVal)
253299 ){
253300 rc = sqlite3Fts5DecodeLocaleValue(pVal, ppText, pnText, &pLoc, &nLoc);
253301 }else{
253302 *ppText = (const char*)sqlite3_value_text(pVal);
253303 *pnText = sqlite3_value_bytes(pVal);
253304 if( pConfig->bLocale && pConfig->eContent==FTS5_CONTENT_NORMAL ){
253305 pLoc = (const char*)sqlite3_column_text(pStmt, iCol+1+pConfig->nCol);
253306 nLoc = sqlite3_column_bytes(pStmt, iCol+1+pConfig->nCol);
253307 }
253308 }
253309 sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
253310 return rc;
253311 }
253312
253313 static int fts5ApiColumnText(
253314 Fts5Context *pCtx,
253315 int iCol,
253316 const char **pz,
@@ -253220,14 +253327,12 @@
253327 *pz = 0;
253328 *pn = 0;
253329 }else{
253330 rc = fts5SeekCursor(pCsr, 0);
253331 if( rc==SQLITE_OK ){
253332 rc = fts5TextFromStmt(pTab->pConfig, pCsr->pStmt, iCol, pz, pn);
253333 sqlite3Fts5ClearLocale(pTab->pConfig);
 
 
253334 }
253335 }
253336 return rc;
253337 }
253338
@@ -253265,21 +253370,19 @@
253370 if( aPopulator==0 ) rc = SQLITE_NOMEM;
253371 if( rc==SQLITE_OK ){
253372 rc = fts5SeekCursor(pCsr, 0);
253373 }
253374 for(i=0; i<pConfig->nCol && rc==SQLITE_OK; i++){
 
253375 const char *z = 0;
253376 int n = 0;
253377 rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
 
253378 if( rc==SQLITE_OK ){
253379 rc = sqlite3Fts5ExprPopulatePoslists(
253380 pConfig, pCsr->pExpr, aPopulator, i, z, n
253381 );
253382 }
253383 sqlite3Fts5ClearLocale(pConfig);
253384 }
253385 sqlite3_free(aPopulator);
253386
253387 if( pCsr->pSorter ){
253388 sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid);
@@ -253461,21 +253564,18 @@
253564 rc = fts5SeekCursor(pCsr, 0);
253565 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
253566 if( pConfig->abUnindexed[i]==0 ){
253567 const char *z = 0;
253568 int n = 0;
 
 
 
253569 pCsr->aColumnSize[i] = 0;
253570 rc = fts5TextFromStmt(pConfig, pCsr->pStmt, i, &z, &n);
253571 if( rc==SQLITE_OK ){
253572 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_AUX,
253573 z, n, (void*)&pCsr->aColumnSize[i], fts5ColumnSizeCb
253574 );
 
253575 }
253576 sqlite3Fts5ClearLocale(pConfig);
253577 }
253578 }
253579 }
253580 CsrFlagClear(pCsr, FTS5CSR_REQUIRE_DOCSIZE);
253581 }
@@ -253743,41 +253843,18 @@
253843 && pConfig->eContent!=FTS5_CONTENT_NONE
253844 && pConfig->bLocale
253845 ){
253846 rc = fts5SeekCursor(pCsr, 0);
253847 if( rc==SQLITE_OK ){
253848 const char *zDummy = 0;
253849 int nDummy = 0;
253850 rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &zDummy, &nDummy);
253851 if( rc==SQLITE_OK ){
253852 *pzLocale = pConfig->t.pLocale;
253853 *pnLocale = pConfig->t.nLocale;
253854 }
253855 sqlite3Fts5ClearLocale(pConfig);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253856 }
253857 }
253858
253859 return rc;
253860 }
@@ -253994,61 +254071,10 @@
254071
254072 sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
254073 return rc;
254074 }
254075
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254076 /*
254077 ** This is the xColumn method, called by SQLite to request a value from
254078 ** the row that the supplied cursor currently points to.
254079 */
254080 static int fts5ColumnMethod(
@@ -254101,12 +254127,26 @@
254127 }else if( bNochange==0 || pConfig->eContent!=FTS5_CONTENT_NORMAL ){
254128 pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
254129 rc = fts5SeekCursor(pCsr, 1);
254130 if( rc==SQLITE_OK ){
254131 sqlite3_value *pVal = sqlite3_column_value(pCsr->pStmt, iCol+1);
254132 if( pConfig->bLocale
254133 && pConfig->eContent==FTS5_CONTENT_EXTERNAL
254134 && sqlite3Fts5IsLocaleValue(pConfig, pVal)
254135 ){
254136 const char *z = 0;
254137 int n = 0;
254138 rc = fts5TextFromStmt(pConfig, pCsr->pStmt, iCol, &z, &n);
254139 if( rc==SQLITE_OK ){
254140 sqlite3_result_text(pCtx, z, n, SQLITE_TRANSIENT);
254141 }
254142 sqlite3Fts5ClearLocale(pConfig);
254143 }else{
254144 sqlite3_result_value(pCtx, pVal);
254145 }
254146 }
254147
254148 pConfig->pzErrmsg = 0;
254149 }
254150 }
254151
254152 return rc;
@@ -254625,11 +254665,11 @@
254665 int nArg, /* Number of args */
254666 sqlite3_value **apUnused /* Function arguments */
254667 ){
254668 assert( nArg==0 );
254669 UNUSED_PARAM2(nArg, apUnused);
254670 sqlite3_result_text(pCtx, "fts5: 2024-09-17 22:57:08 a63e412b6b2939422ecfa99d91fccb7a9c61e1533bb0db20ff12f3815ef41a2c", -1, SQLITE_TRANSIENT);
254671 }
254672
254673 /*
254674 ** Implementation of fts5_locale(LOCALE, TEXT) function.
254675 **
@@ -254664,34 +254704,32 @@
254704 nText = sqlite3_value_bytes(apArg[1]);
254705
254706 if( zLocale==0 || zLocale[0]=='\0' ){
254707 sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
254708 }else{
254709 Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx);
254710 u8 *pBlob = 0;
254711 u8 *pCsr = 0;
254712 int nBlob = 0;
 
 
254713
254714 nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText;
254715 pBlob = (u8*)sqlite3_malloc(nBlob);
254716 if( pBlob==0 ){
254717 sqlite3_result_error_nomem(pCtx);
254718 return;
254719 }
254720
254721 pCsr = pBlob;
254722 memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE);
254723 pCsr += FTS5_LOCALE_HDR_SIZE;
254724 memcpy(pCsr, zLocale, nLocale);
254725 pCsr += nLocale;
254726 (*pCsr++) = 0x00;
254727 if( zText ) memcpy(pCsr, zText, nText);
254728 assert( &pCsr[nText]==&pBlob[nBlob] );
254729
254730 sqlite3_result_blob(pCtx, pBlob, nBlob, sqlite3_free);
 
254731 }
254732 }
254733
254734 /*
254735 ** Return true if zName is the extension on one of the shadow tables used
@@ -254789,10 +254827,20 @@
254827 pGlobal->api.xCreateFunction = fts5CreateAux;
254828 pGlobal->api.xCreateTokenizer = fts5CreateTokenizer;
254829 pGlobal->api.xFindTokenizer = fts5FindTokenizer;
254830 pGlobal->api.xCreateTokenizer_v2 = fts5CreateTokenizer_v2;
254831 pGlobal->api.xFindTokenizer_v2 = fts5FindTokenizer_v2;
254832
254833 /* Initialize pGlobal->aLocaleHdr[] to a 128-bit pseudo-random vector.
254834 ** The constants below were generated randomly. */
254835 sqlite3_randomness(sizeof(pGlobal->aLocaleHdr), pGlobal->aLocaleHdr);
254836 pGlobal->aLocaleHdr[0] ^= 0xF924976D;
254837 pGlobal->aLocaleHdr[1] ^= 0x16596E13;
254838 pGlobal->aLocaleHdr[2] ^= 0x7C80BEAA;
254839 pGlobal->aLocaleHdr[3] ^= 0x9B03A67F;
254840 assert( sizeof(pGlobal->aLocaleHdr)==16 );
254841
254842 rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy);
254843 if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db);
254844 if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db);
254845 if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api);
254846 if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api);
@@ -254944,10 +254992,34 @@
254992 #define FTS5_STMT_REPLACE_DOCSIZE 7
254993 #define FTS5_STMT_DELETE_DOCSIZE 8
254994 #define FTS5_STMT_LOOKUP_DOCSIZE 9
254995 #define FTS5_STMT_REPLACE_CONFIG 10
254996 #define FTS5_STMT_SCAN 11
254997
254998 /*
254999 ** Return a pointer to a buffer obtained from sqlite3_malloc() that contains
255000 ** nBind comma-separated question marks. e.g. if nBind is passed 5, this
255001 ** function returns "?,?,?,?,?".
255002 **
255003 ** If *pRc is not SQLITE_OK when this function is called, it is a no-op and
255004 ** NULL is returned immediately. Or, if the attempt to malloc a buffer
255005 ** fails, then *pRc is set to SQLITE_NOMEM and NULL is returned. Otherwise,
255006 ** if it is SQLITE_OK when this function is called and the malloc() succeeds,
255007 ** *pRc is left unchanged.
255008 */
255009 static char *fts5BindingsList(int *pRc, int nBind){
255010 char *zBind = sqlite3Fts5MallocZero(pRc, 1 + nBind*2);
255011 if( zBind ){
255012 int ii;
255013 for(ii=0; ii<nBind; ii++){
255014 zBind[ii*2] = '?';
255015 zBind[ii*2 + 1] = ',';
255016 }
255017 zBind[ii*2-1] = '\0';
255018 }
255019 return zBind;
255020 }
255021
255022 /*
255023 ** Prepare the two insert statements - Fts5Storage.pInsertContent and
255024 ** Fts5Storage.pInsertDocsize - if they have not already been prepared.
255025 ** Return SQLITE_OK if successful, or an SQLite error code if an error
@@ -255013,23 +255085,24 @@
255085 zSql = sqlite3_mprintf(azStmt[eStmt],
255086 pC->zContentExprlist, pC->zContent, pC->zContentRowid
255087 );
255088 break;
255089
255090 case FTS5_STMT_INSERT_CONTENT: {
255091 int nCol = 0;
 
255092 char *zBind;
255093 int i;
255094
255095 nCol = 1 + pC->nCol;
255096 if( pC->bLocale ){
255097 for(i=0; i<pC->nCol; i++){
255098 if( pC->abUnindexed[i]==0 ) nCol++;
 
255099 }
255100 }
255101
255102 zBind = fts5BindingsList(&rc, nCol);
255103 if( zBind ){
255104 zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind);
255105 sqlite3_free(zBind);
255106 }
255107 break;
255108 }
@@ -255216,11 +255289,11 @@
255289 p->pIndex = pIndex;
255290
255291 if( bCreate ){
255292 if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
255293 int nDefn = 32 + pConfig->nCol*10;
255294 char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 20);
255295 if( zDefn==0 ){
255296 rc = SQLITE_NOMEM;
255297 }else{
255298 int i;
255299 int iOff;
@@ -255227,10 +255300,18 @@
255300 sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY");
255301 iOff = (int)strlen(zDefn);
255302 for(i=0; i<pConfig->nCol; i++){
255303 sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i);
255304 iOff += (int)strlen(&zDefn[iOff]);
255305 }
255306 if( pConfig->bLocale ){
255307 for(i=0; i<pConfig->nCol; i++){
255308 if( pConfig->abUnindexed[i]==0 ){
255309 sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", l%d", i);
255310 iOff += (int)strlen(&zDefn[iOff]);
255311 }
255312 }
255313 }
255314 rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr);
255315 }
255316 sqlite3_free(zDefn);
255317 }
@@ -255379,33 +255460,43 @@
255460 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
255461 if( pConfig->abUnindexed[iCol-1]==0 ){
255462 sqlite3_value *pVal = 0;
255463 const char *pText = 0;
255464 int nText = 0;
255465 const char *pLoc = 0;
255466 int nLoc = 0;
255467
255468 assert( pSeek==0 || apVal==0 );
255469 assert( pSeek!=0 || apVal!=0 );
255470 if( pSeek ){
255471 pVal = sqlite3_column_value(pSeek, iCol);
255472 }else{
255473 pVal = apVal[iCol-1];
255474 }
255475
255476 if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
255477 rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255478 }else{
255479 pText = (const char*)sqlite3_value_text(pVal);
255480 nText = sqlite3_value_bytes(pVal);
255481 if( pConfig->bLocale && pSeek ){
255482 pLoc = (const char*)sqlite3_column_text(pSeek, iCol + pConfig->nCol);
255483 nLoc = sqlite3_column_bytes(pSeek, iCol + pConfig->nCol);
255484 }
255485 }
255486
255487 if( rc==SQLITE_OK ){
255488 sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
255489 ctx.szCol = 0;
255490 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
255491 pText, nText, (void*)&ctx, fts5StorageInsertCallback
255492 );
255493 p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
255494 if( rc==SQLITE_OK && p->aTotalSize[iCol-1]<0 ){
255495 rc = FTS5_CORRUPT;
255496 }
255497 sqlite3Fts5ClearLocale(pConfig);
255498 }
255499 }
255500 }
255501 if( rc==SQLITE_OK && p->nTotalRow<1 ){
255502 rc = FTS5_CORRUPT;
@@ -255660,24 +255751,39 @@
255751 sqlite3Fts5BufferZero(&buf);
255752 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255753 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255754 ctx.szCol = 0;
255755 if( pConfig->abUnindexed[ctx.iCol]==0 ){
 
255756 int nText = 0; /* Size of pText in bytes */
255757 const char *pText = 0; /* Pointer to buffer containing text value */
255758 int nLoc = 0; /* Size of pLoc in bytes */
255759 const char *pLoc = 0; /* Pointer to buffer containing text value */
255760
255761 sqlite3_value *pVal = sqlite3_column_value(pScan, ctx.iCol+1);
255762 if( pConfig->eContent==FTS5_CONTENT_EXTERNAL
255763 && sqlite3Fts5IsLocaleValue(pConfig, pVal)
255764 ){
255765 rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255766 }else{
255767 pText = (const char*)sqlite3_value_text(pVal);
255768 nText = sqlite3_value_bytes(pVal);
255769 if( pConfig->bLocale ){
255770 int iCol = ctx.iCol + 1 + pConfig->nCol;
255771 pLoc = (const char*)sqlite3_column_text(pScan, iCol);
255772 nLoc = sqlite3_column_bytes(pScan, iCol);
255773 }
255774 }
255775
 
255776 if( rc==SQLITE_OK ){
255777 sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
255778 rc = sqlite3Fts5Tokenize(pConfig,
255779 FTS5_TOKENIZE_DOCUMENT,
255780 pText, nText,
255781 (void*)&ctx,
255782 fts5StorageInsertCallback
255783 );
255784 sqlite3Fts5ClearLocale(pConfig);
255785 }
255786 }
255787 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255788 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255789 }
@@ -255756,33 +255862,49 @@
255862 rc = fts5StorageNewRowid(p, piRowid);
255863 }
255864 }else{
255865 sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */
255866 int i; /* Counter variable */
255867 int nIndexed = 0; /* Number indexed columns seen */
255868 rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
255869 if( pInsert ) sqlite3_clear_bindings(pInsert);
255870
255871 /* Bind the rowid value */
255872 sqlite3_bind_value(pInsert, 1, apVal[1]);
255873
255874 /* Loop through values for user-defined columns. i=2 is the leftmost
255875 ** user-defined column. As is column 1 of pSavedRow. */
255876 for(i=2; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
255877 int bUnindexed = pConfig->abUnindexed[i-2];
255878 sqlite3_value *pVal = apVal[i];
255879
255880 nIndexed += !bUnindexed;
255881 if( sqlite3_value_nochange(pVal) && p->pSavedRow ){
255882 /* This is an UPDATE statement, and column (i-2) was not modified.
255883 ** Retrieve the value from Fts5Storage.pSavedRow instead. */
255884 pVal = sqlite3_column_value(p->pSavedRow, i-1);
255885 if( pConfig->bLocale && bUnindexed==0 ){
255886 sqlite3_bind_value(pInsert, pConfig->nCol + 1 + nIndexed,
255887 sqlite3_column_value(p->pSavedRow, pConfig->nCol + i - 1)
255888 );
255889 }
255890 }else if( sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
255891 const char *pText = 0;
255892 const char *pLoc = 0;
255893 int nText = 0;
255894 int nLoc = 0;
255895 assert( pConfig->bLocale );
255896
255897 rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255898 if( rc==SQLITE_OK ){
 
 
 
 
255899 sqlite3_bind_text(pInsert, i, pText, nText, SQLITE_TRANSIENT);
255900 if( bUnindexed==0 ){
255901 int iLoc = pConfig->nCol + 1 + nIndexed;
255902 sqlite3_bind_text(pInsert, iLoc, pLoc, nLoc, SQLITE_TRANSIENT);
255903 }
 
255904 }
255905
255906 continue;
255907 }
255908
255909 rc = sqlite3_bind_value(pInsert, i, pVal);
255910 }
@@ -255817,27 +255939,41 @@
255939 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
255940 }
255941 for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
255942 ctx.szCol = 0;
255943 if( pConfig->abUnindexed[ctx.iCol]==0 ){
 
255944 int nText = 0; /* Size of pText in bytes */
255945 const char *pText = 0; /* Pointer to buffer containing text value */
255946 int nLoc = 0; /* Size of pText in bytes */
255947 const char *pLoc = 0; /* Pointer to buffer containing text value */
255948
255949 sqlite3_value *pVal = apVal[ctx.iCol+2];
 
255950 if( p->pSavedRow && sqlite3_value_nochange(pVal) ){
255951 pVal = sqlite3_column_value(p->pSavedRow, ctx.iCol+1);
255952 if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){
255953 int iCol = ctx.iCol + 1 + pConfig->nCol;
255954 pLoc = (const char*)sqlite3_column_text(p->pSavedRow, iCol);
255955 nLoc = sqlite3_column_bytes(p->pSavedRow, iCol);
255956 }
255957 }else{
255958 pVal = apVal[ctx.iCol+2];
255959 }
255960
255961 if( pConfig->bLocale && sqlite3Fts5IsLocaleValue(pConfig, pVal) ){
255962 rc = sqlite3Fts5DecodeLocaleValue(pVal, &pText, &nText, &pLoc, &nLoc);
255963 }else{
255964 pText = (const char*)sqlite3_value_text(pVal);
255965 nText = sqlite3_value_bytes(pVal);
255966 }
255967
255968 if( rc==SQLITE_OK ){
255969 sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
255970 rc = sqlite3Fts5Tokenize(pConfig,
255971 FTS5_TOKENIZE_DOCUMENT, pText, nText, (void*)&ctx,
255972 fts5StorageInsertCallback
255973 );
255974 sqlite3Fts5ClearLocale(pConfig);
255975 }
255976 }
255977 sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
255978 p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
255979 }
@@ -255998,41 +256134,65 @@
256134 }
256135 if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){
256136 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
256137 }
256138 for(i=0; rc==SQLITE_OK && i<pConfig->nCol; i++){
256139 if( pConfig->abUnindexed[i]==0 ){
256140 const char *pText = 0;
256141 int nText = 0;
256142 const char *pLoc = 0;
256143 int nLoc = 0;
256144 sqlite3_value *pVal = sqlite3_column_value(pScan, i+1);
256145
256146 if( pConfig->eContent==FTS5_CONTENT_EXTERNAL
256147 && sqlite3Fts5IsLocaleValue(pConfig, pVal)
256148 ){
256149 rc = sqlite3Fts5DecodeLocaleValue(
256150 pVal, &pText, &nText, &pLoc, &nLoc
256151 );
256152 }else{
256153 if( pConfig->eContent==FTS5_CONTENT_NORMAL && pConfig->bLocale ){
256154 int iCol = i + 1 + pConfig->nCol;
256155 pLoc = (const char*)sqlite3_column_text(pScan, iCol);
256156 nLoc = sqlite3_column_bytes(pScan, iCol);
256157 }
256158 pText = (const char*)sqlite3_value_text(pVal);
256159 nText = sqlite3_value_bytes(pVal);
256160 }
256161
256162 ctx.iCol = i;
256163 ctx.szCol = 0;
256164
256165 if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256166 rc = sqlite3Fts5TermsetNew(&ctx.pTermset);
256167 }
256168
256169 if( rc==SQLITE_OK ){
256170 sqlite3Fts5SetLocale(pConfig, pLoc, nLoc);
256171 rc = sqlite3Fts5Tokenize(pConfig,
256172 FTS5_TOKENIZE_DOCUMENT,
256173 pText, nText,
256174 (void*)&ctx,
256175 fts5StorageIntegrityCallback
256176 );
256177 sqlite3Fts5ClearLocale(pConfig);
256178 }
256179
256180 /* If this is not a columnsize=0 database, check that the number
256181 ** of tokens in the value matches the aColSize[] value read from
256182 ** the %_docsize table. */
256183 if( rc==SQLITE_OK
256184 && pConfig->bColumnsize
256185 && ctx.szCol!=aColSize[i]
256186 ){
256187 rc = FTS5_CORRUPT;
256188 }
256189 aTotalSize[i] += ctx.szCol;
256190 if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){
256191 sqlite3Fts5TermsetFree(ctx.pTermset);
256192 ctx.pTermset = 0;
256193 }
256194 }
256195 }
256196 sqlite3Fts5TermsetFree(ctx.pTermset);
256197 ctx.pTermset = 0;
256198
256199
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.47.0"
150150
#define SQLITE_VERSION_NUMBER 3047000
151
-#define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
151
+#define SQLITE_SOURCE_ID "2024-09-17 22:57:08 a63e412b6b2939422ecfa99d91fccb7a9c61e1533bb0db20ff12f3815ef41a2c"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
157157
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.47.0"
150 #define SQLITE_VERSION_NUMBER 3047000
151 #define SQLITE_SOURCE_ID "2024-09-02 21:59:31 7891a266c4425722ae8b9231397ef9e42e2432be9e6b70632dfaf9ff15300d2c"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
157
--- extsrc/sqlite3.h
+++ extsrc/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.47.0"
150 #define SQLITE_VERSION_NUMBER 3047000
151 #define SQLITE_SOURCE_ID "2024-09-17 22:57:08 a63e412b6b2939422ecfa99d91fccb7a9c61e1533bb0db20ff12f3815ef41a2c"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
157

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button